first init
This commit is contained in:
parent
837003ea32
commit
40be5eb96d
|
@ -0,0 +1,44 @@
|
|||
cmake_minimum_required(VERSION 3.8)
|
||||
|
||||
project(ini_test)
|
||||
|
||||
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)
|
||||
include_directories(${TINY_ROOT}/components/utils/Bcrypt/include)
|
||||
|
||||
aux_source_directory(${ARCH_ROOT}/common ARCH_COMMON_SRCS)
|
||||
aux_source_directory(${ARCH_ROOT}/posix/gcc ARCH_POSIX_SRCS)
|
||||
|
||||
aux_source_directory(${TINY_ROOT}/components/utils/Bcrypt/src BCRYPT_SRCS)
|
||||
|
||||
set(ARCH_SRCS ${ARCH_COMMON_SRCS} ${ARCH_POSIX_SRCS})
|
||||
|
||||
set(TINY_SRCS ${ARCH_SRCS} ${CMSIS_SRCS} ${EVTDRV_SRCS} ${PM_SRCS} ${CORE_SRCS} ${BCRYPT_SRCS} )
|
||||
|
||||
include_directories(./)
|
||||
include_directories(./inc)
|
||||
|
||||
set(APP_SRCS src/main.c)
|
||||
|
||||
add_executable(bcrypt_demo ${APP_SRCS} ${TINY_SRCS})
|
||||
|
||||
target_link_libraries(bcrypt_demo 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)/libbcrypt_demo.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,42 @@
|
|||
# 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
|
||||
./bcrypt_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,84 @@
|
|||
#include "cmsis_os.h"
|
||||
#include "bcrypt.h"
|
||||
|
||||
#define TASK1_STK_SIZE 512
|
||||
void task1(void *arg);
|
||||
osThreadDef(task1, osPriorityNormal, 1, TASK1_STK_SIZE);
|
||||
|
||||
int Bcrypt(const char *Src, char *Dst)
|
||||
{
|
||||
int Ret = -1;
|
||||
char Salt[BCRYPT_HASHSIZE] = {0};
|
||||
char Hash[BCRYPT_HASHSIZE] = {0};
|
||||
|
||||
if(NULL == Src)
|
||||
{
|
||||
printf("Src is NULL!\n");
|
||||
goto ErrorHandler;
|
||||
}
|
||||
|
||||
if(NULL == Dst)
|
||||
{
|
||||
printf("Dst is NULL!\n");
|
||||
goto ErrorHandler;
|
||||
}
|
||||
|
||||
Ret = bcrypt_gensalt(12, Salt);
|
||||
if(Ret < 0)
|
||||
{
|
||||
printf("bcrypt_gensalt failed!\n");
|
||||
goto ErrorHandler;
|
||||
}
|
||||
|
||||
Ret = bcrypt_hashpw(Src, Salt, Hash);
|
||||
if(Ret < 0)
|
||||
{
|
||||
printf("bcrypt_hashpw failed!\n");
|
||||
goto ErrorHandler;
|
||||
}
|
||||
|
||||
memcpy(Dst, Hash, sizeof(Hash));
|
||||
|
||||
return 0;
|
||||
|
||||
ErrorHandler:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void task1(void *arg)
|
||||
{
|
||||
int Ret = -1;
|
||||
char Hash[BCRYPT_HASHSIZE] = {0};
|
||||
const char *DeviceKey = "8HLWBzFvOoZDo9wHZnCAKaAZeb8";
|
||||
|
||||
Ret = Bcrypt(DeviceKey, Hash);
|
||||
if(Ret < 0)
|
||||
{
|
||||
printf("Bcrypt failed!\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
printf("Bcrypt DeviceKey = %s\n", Hash);
|
||||
|
||||
while(1)
|
||||
{
|
||||
printf("BcryptTest success!\n");
|
||||
osDelay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
void application_entry(void *arg)
|
||||
{
|
||||
osThreadCreate(osThread(task1), NULL); // Create task1
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
osKernelInitialize(); //TOS Tiny kernel initialize
|
||||
application_entry(NULL);
|
||||
osKernelStart(); //Start TOS Tiny
|
||||
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -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,42 @@
|
|||
# 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,44 @@
|
|||
cmake_minimum_required(VERSION 3.8)
|
||||
|
||||
project(ini_test)
|
||||
|
||||
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)
|
||||
include_directories(${TINY_ROOT}/components/utils/INI/include)
|
||||
|
||||
aux_source_directory(${ARCH_ROOT}/common ARCH_COMMON_SRCS)
|
||||
aux_source_directory(${ARCH_ROOT}/posix/gcc ARCH_POSIX_SRCS)
|
||||
|
||||
aux_source_directory(${TINY_ROOT}/components/utils/INI/src INI_SRCS)
|
||||
|
||||
set(ARCH_SRCS ${ARCH_COMMON_SRCS} ${ARCH_POSIX_SRCS})
|
||||
|
||||
set(TINY_SRCS ${ARCH_SRCS} ${CMSIS_SRCS} ${EVTDRV_SRCS} ${PM_SRCS} ${CORE_SRCS} ${INI_SRCS} )
|
||||
|
||||
include_directories(./)
|
||||
include_directories(./inc)
|
||||
|
||||
set(APP_SRCS src/main.c)
|
||||
|
||||
add_executable(inidemo ${APP_SRCS} ${TINY_SRCS})
|
||||
|
||||
target_link_libraries(inidemo 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)/libini_demo.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,42 @@
|
|||
# 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
|
||||
./inidemo
|
||||
```
|
||||
|
||||
## 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,170 @@
|
|||
#include "cmsis_os.h"
|
||||
#include "iniparser.h"
|
||||
#define CONFIG_NAME "Config.ini"
|
||||
|
||||
struct DataInfo_t
|
||||
{
|
||||
int InitData;
|
||||
int VolumeData;
|
||||
int LanguageVersion;
|
||||
};
|
||||
|
||||
#define TASK1_STK_SIZE 512
|
||||
void task1(void *arg);
|
||||
osThreadDef(task1, osPriorityNormal, 1, TASK1_STK_SIZE);
|
||||
|
||||
void task1(void *arg)
|
||||
{
|
||||
int Len = -1;
|
||||
int Ret = -1;
|
||||
char Buf[128];
|
||||
char *DataPtr = NULL;
|
||||
struct DataInfo_t Data;
|
||||
FILE *IniTest = NULL ;
|
||||
FILE *DefaultIni = NULL;
|
||||
dictionary *ConfigIni = NULL;
|
||||
|
||||
/*1. Create ini config file*/
|
||||
IniTest = fopen(CONFIG_NAME, "w");
|
||||
if(NULL == IniTest)
|
||||
{
|
||||
printf("IniTest is Null!\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
fprintf(IniTest,
|
||||
"[Setting]\n"
|
||||
"init_data=0;\n"
|
||||
"volume_data=1;\n"
|
||||
"language_version=1;\n"
|
||||
);
|
||||
|
||||
Ret = fclose(IniTest);
|
||||
if(Ret != 0)
|
||||
{
|
||||
printf("close IniTest fail!\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
IniTest = NULL;
|
||||
|
||||
IniTest = fopen(CONFIG_NAME, "r");
|
||||
if(NULL == IniTest)
|
||||
{
|
||||
printf("IniTest is Null!\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
memset(Buf, 0, sizeof(Buf));
|
||||
while(fgets(Buf, sizeof(Buf), IniTest))
|
||||
{
|
||||
printf("Buf: %s", Buf);
|
||||
}
|
||||
|
||||
fclose(IniTest);
|
||||
IniTest = NULL;
|
||||
|
||||
putchar('\n');
|
||||
|
||||
/*2. Test read ini config file data*/
|
||||
ConfigIni = iniparser_load(CONFIG_NAME);
|
||||
if(NULL == ConfigIni)
|
||||
{
|
||||
printf("ConfigIni is NULL!\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
//iniparser_dump(ConfigIni, stderr);
|
||||
Data.InitData = iniparser_getint(ConfigIni,"Setting:init_data",-1);
|
||||
if(-1 == Data.InitData)
|
||||
{
|
||||
printf("iniparser_getint fail!\n");
|
||||
return ;
|
||||
}
|
||||
Data.VolumeData = iniparser_getint(ConfigIni,"Setting:volume_data",-1);
|
||||
if(-1 == Data.VolumeData)
|
||||
{
|
||||
printf("iniparser_getint fail!\n");
|
||||
return ;
|
||||
}
|
||||
Data.LanguageVersion = iniparser_getint(ConfigIni,"Setting:language_version",-1);
|
||||
if(-1 == Data.LanguageVersion)
|
||||
{
|
||||
printf("iniparser_getint fail!\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
printf("Data.InitData:%d\n", Data.InitData);
|
||||
printf("Data.VolumeData:%d\n", Data.VolumeData);
|
||||
printf("Data.LanguageVersion:%d\n", Data.LanguageVersion);
|
||||
|
||||
/* 3. Set modify one of the parameters*/
|
||||
iniparser_set(ConfigIni,"Setting:init_data", "111");
|
||||
iniparser_set(ConfigIni,"Setting:volume_data", "222");
|
||||
iniparser_set(ConfigIni,"Setting:language_version", "333");
|
||||
|
||||
putchar('\n');
|
||||
|
||||
/*4. Write data to int config file*/
|
||||
DefaultIni = fopen(CONFIG_NAME, "w");
|
||||
if(NULL == DefaultIni)
|
||||
{
|
||||
printf("DefaultIni is NULL!\n");
|
||||
return ;
|
||||
}
|
||||
iniparser_dump_ini(ConfigIni, DefaultIni);
|
||||
Ret = fclose(DefaultIni);
|
||||
if(Ret != 0)
|
||||
{
|
||||
printf("close DefaultIni fail!\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
/*5.Read the modified Config ini file data*/
|
||||
Data.InitData = iniparser_getint(ConfigIni, "Setting:init_data", -1);
|
||||
if(-1 == Data.InitData)
|
||||
{
|
||||
printf("iniparser_getint fail!\n");
|
||||
return ;
|
||||
}
|
||||
Data.VolumeData = iniparser_getint(ConfigIni, "Setting:volume_data", -1);
|
||||
if(-1 == Data.VolumeData)
|
||||
{
|
||||
printf("iniparser_getint fail!\n");
|
||||
return ;
|
||||
}
|
||||
Data.LanguageVersion = iniparser_getint(ConfigIni, "Setting:language_version", -1);
|
||||
if(-1 == Data.LanguageVersion)
|
||||
{
|
||||
printf("iniparser_getint fail!\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
printf("Data.InitData:%d\n", Data.InitData);
|
||||
printf("Data.VolumeData:%d\n", Data.VolumeData);
|
||||
printf("Data.LanguageVersion:%d\n", Data.LanguageVersion);
|
||||
|
||||
iniparser_freedict(ConfigIni);
|
||||
|
||||
while(1)
|
||||
{
|
||||
printf("Ini test success!\n");
|
||||
osDelay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
void application_entry(void *arg)
|
||||
{
|
||||
osThreadCreate(osThread(task1), NULL); // Create task1
|
||||
}
|
||||
|
||||
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,91 @@
|
|||
# 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);
|
||||
}
|
34
README.md
34
README.md
|
@ -1,32 +1,2 @@
|
|||
## 项目名称
|
||||
> 请介绍一下你的项目吧
|
||||
|
||||
|
||||
|
||||
## 运行条件
|
||||
> 列出运行该项目所必须的条件和相关依赖
|
||||
* 条件一
|
||||
* 条件二
|
||||
* 条件三
|
||||
|
||||
|
||||
|
||||
## 运行说明
|
||||
> 说明如何运行和使用你的项目,建议给出具体的步骤说明
|
||||
* 操作一
|
||||
* 操作二
|
||||
* 操作三
|
||||
|
||||
|
||||
|
||||
## 测试说明
|
||||
> 如果有测试相关内容需要说明,请填写在这里
|
||||
|
||||
|
||||
|
||||
## 技术架构
|
||||
> 使用的技术框架或系统架构图等相关说明,请填写在这里
|
||||
|
||||
|
||||
## 协作者
|
||||
> 高效的协作会激发无尽的创造力,将他们的名字记录在这里吧
|
||||
## TobudOS 中立开放、绿色科技 - 开放原子开源基金会指导下的物联网操作系统开源社区
|
||||
> TobudOS 是面向物联网领域开发的实时操作系统,早期版本基于腾讯自研的物联网操作系统TencentOS Tiny,2020年由腾讯捐赠到开放原子开源基金会进行孵化,2023年正式更名为TobudOS,TobudOS具有低功耗,低资源占用,模块化,安全可靠等特点,可有效提升物联网终端产品开发效率,提供精简的 RTOS 内核,内核组件可裁剪可配置,可快速移植到多种主流 MCU (如 STM32 全系列) 及模组芯片上。而且,基于 RTOS 内核提供了丰富的物联网组件,内部集成主流物联网协议栈(如 CoAP/MQTT/TLS/DTLS/LoRaWAN/NB-IoT 等),可助力物联网终端设备及业务快速接入物联网云平台。
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
###################################################################
|
||||
#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 ! -d 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)))
|
||||
|
||||
####################################################################
|
||||
|
||||
|
||||
TREE_LIB_ENABLE=0
|
||||
lib=
|
||||
subdirs=
|
||||
ifneq (help,$(findstring help,$(MAKECMDGOALS)))
|
||||
|
||||
ifeq (, $(strip ${BP}))
|
||||
$(error when compile arch/, must specify BP obviously , see `make help`)
|
||||
endif
|
||||
|
||||
include ${QTOP}/qmk/board-pack/bp.${BP}
|
||||
|
||||
|
||||
ifeq (,$(strip ${ARCH_LSRCS}))
|
||||
$(error when compile arch/, must specify ARCH_LSRCS on your bp.${BP} , see `make help`)
|
||||
endif
|
||||
endif
|
||||
|
||||
# arch src should be specify by bp
|
||||
LSRCS := $(subst $(QTOP)/arch/,, ${ARCH_LSRCS})
|
||||
include ${QTOP}/qmk/generic/Make.tpl
|
||||
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _PORT_H_
|
||||
#define _PORT_H_
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT) && (TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT == 1u)
|
||||
__PORT__ uint32_t port_cpu_clz(uint32_t);
|
||||
#endif
|
||||
|
||||
__PORT__ void port_int_disable(void);
|
||||
|
||||
__PORT__ void port_int_enable(void);
|
||||
|
||||
__PORT__ cpu_cpsr_t port_cpsr_save(void);
|
||||
|
||||
__PORT__ void port_cpsr_restore(cpu_cpsr_t cpsr);
|
||||
|
||||
__PORT__ void port_cpu_reset(void);
|
||||
|
||||
__PORT__ void port_sched_start(void) __NO_RETURN__;
|
||||
|
||||
__PORT__ void port_context_switch(void);
|
||||
|
||||
__PORT__ void port_irq_context_switch(void);
|
||||
|
||||
__PORT__ void port_systick_config(uint32_t cycle_per_tick);
|
||||
|
||||
__PORT__ void port_systick_priority_set(uint32_t prio);
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN > 0u
|
||||
|
||||
__PORT__ void port_systick_resume(void);
|
||||
|
||||
__PORT__ void port_systick_suspend(void);
|
||||
|
||||
__PORT__ void port_systick_reload(uint32_t cycle_per_tick);
|
||||
|
||||
__PORT__ void port_systick_pending_reset(void);
|
||||
|
||||
__PORT__ k_time_t port_systick_max_delay_millisecond(void);
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__PORT__ void port_sleep_mode_enter(void);
|
||||
|
||||
__PORT__ void port_stop_mode_enter(void);
|
||||
|
||||
__PORT__ void port_standby_mode_enter(void);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _PORT_H_ */
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos_k.h"
|
||||
#include "arc/arc_timer.h"
|
||||
#include "board.h"
|
||||
#include "arc/arc_exception.h"
|
||||
|
||||
__PORT__ void port_cpu_reset(void)
|
||||
{
|
||||
exc_entry_reset();
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_config(uint32_t cycle_per_tick)
|
||||
{
|
||||
arc_timer_int_clear(0);
|
||||
board_timer_update(cycle_per_tick);
|
||||
}
|
||||
__PORT__ void port_systick_priority_set(uint32_t prio)
|
||||
{
|
||||
int_pri_set(BOARD_OS_TIMER_INTNO, prio);
|
||||
}
|
||||
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN > 0u
|
||||
|
||||
__PORT__ k_time_t port_systick_max_delay_millisecond(void)
|
||||
{
|
||||
k_time_t max_millisecond;
|
||||
uint32_t max_cycle;
|
||||
|
||||
max_cycle = arc_aux_read(AUX_TIMER0_LIMIT); // AUX_TIMER0_CNT, reset value 0x00FFFFFF
|
||||
max_millisecond = (k_time_t)((uint64_t)max_cycle * K_TIME_MILLISEC_PER_SEC / TOS_CFG_CPU_CLOCK); // CLOCK: cycle per second
|
||||
return max_millisecond;
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_resume(void)
|
||||
{
|
||||
arc_aux_write(AUX_TIMER0_CTRL, TIMER_CTRL_IE); // enables the generation of an interrupt after the timer has reached its limit
|
||||
arc_aux_write(AUX_TIMER0_CNT, 0); // writing to this register sets 0 for the timer, and restarts the timer
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_suspend(void)
|
||||
{
|
||||
arc_aux_write(AUX_TIMER0_CTRL, TIMER_CTRL_NH); // counting is suspended during host debugger interactions with the processor.
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_reload(uint32_t cycle_per_tick)
|
||||
{
|
||||
uint32_t max_cycle;
|
||||
uint32_t systick_value;
|
||||
|
||||
max_cycle = arc_aux_read(AUX_TIMER0_LIMIT); // AUX_TIMER0_CNT, reset value 0x00FFFFFF
|
||||
systick_value = arc_aux_read(AUX_TIMER0_CNT);
|
||||
|
||||
if (max_cycle - systick_value > cycle_per_tick - 1u) {
|
||||
arc_aux_write(AUX_TIMER0_LIMIT, max_cycle);
|
||||
} else {
|
||||
arc_aux_write(AUX_TIMER0_LIMIT, (cycle_per_tick - 1u) + systick_value);
|
||||
}
|
||||
|
||||
arc_aux_write(AUX_TIMER0_CNT, 0);
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_pending_reset(void)
|
||||
{
|
||||
arc_aux_write(AUX_TIMER0_CTRL, TIMER_CTRL_IP); // interrupt pending
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__PORT__ void port_sleep_mode_enter(void)
|
||||
{
|
||||
Asm("sleep");
|
||||
}
|
||||
|
||||
__PORT__ void port_stop_mode_enter(void)
|
||||
{
|
||||
Asm("brk");
|
||||
}
|
||||
|
||||
__PORT__ void port_standby_mode_enter(void)
|
||||
{
|
||||
Asm("nop");
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,28 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _PORT_CONFIG_H_
|
||||
#define _PORT_CONFIG_H_
|
||||
|
||||
#define TOS_CFG_CPU_ADDR_SIZE CPU_WORD_SIZE_32
|
||||
#define TOS_CFG_CPU_DATA_SIZE CPU_WORD_SIZE_32
|
||||
#define TOS_CFG_CPU_STK_GROWTH CPU_STK_GROWTH_DESCENDING
|
||||
#define TOS_CFG_CPU_HRTIMER_EN 0u
|
||||
#define TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT 1u
|
||||
#define TOS_CFG_CPU_BYTE_ORDER 0u
|
||||
|
||||
#endif /* _PORT_CONFIG_H_ */
|
|
@ -0,0 +1,319 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Synopsys, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define __ASSEMBLY__
|
||||
#include "arc.h"
|
||||
#include "arc_asm_common.h"
|
||||
|
||||
.global k_curr_task
|
||||
.global k_next_task
|
||||
|
||||
.global g_exc_nest_count
|
||||
.global g_context_switch_reqflg
|
||||
|
||||
.global tos_knl_irq_enter
|
||||
.global tos_knl_irq_leave
|
||||
|
||||
.text
|
||||
.align 4
|
||||
dispatcher:
|
||||
st sp, [r0] // ld r0, [k_curr_task]
|
||||
ld sp, [r1] // ld r1, [k_next_task]
|
||||
# k_curr_task = k_next_task;
|
||||
st r1, [k_curr_task]
|
||||
pop r0
|
||||
j [r0]
|
||||
|
||||
/* return routine when task dispatch happened in task context */
|
||||
dispatch_r:
|
||||
RESTORE_NONSCRATCH_REGS
|
||||
j [blink]
|
||||
|
||||
|
||||
/*
|
||||
* void port_sched_start(void)
|
||||
*/
|
||||
.global port_sched_start
|
||||
.align 4
|
||||
port_sched_start:
|
||||
ld r0, [k_curr_task]
|
||||
ld sp, [r0]
|
||||
pop r0
|
||||
j [r0]
|
||||
|
||||
|
||||
/*
|
||||
* void port_context_switch(void)
|
||||
*/
|
||||
.global port_context_switch
|
||||
.align 4
|
||||
port_context_switch:
|
||||
SAVE_NONSCRATCH_REGS
|
||||
mov r2, dispatch_r
|
||||
push r2
|
||||
ld r0, [k_curr_task]
|
||||
ld r1, [k_next_task]
|
||||
b dispatcher
|
||||
|
||||
/*
|
||||
* void port_irq_context_switch(void)
|
||||
*/
|
||||
.global port_irq_context_switch
|
||||
.align 4
|
||||
port_irq_context_switch:
|
||||
mov r0, 1
|
||||
st r0, [g_context_switch_reqflg]
|
||||
j [blink]
|
||||
|
||||
|
||||
/*
|
||||
* void start_r(void)
|
||||
*/
|
||||
.global start_r
|
||||
.align 4
|
||||
start_r:
|
||||
pop blink;
|
||||
pop r1
|
||||
pop r2
|
||||
pop r0
|
||||
|
||||
kflag r2
|
||||
j [r1]
|
||||
|
||||
/****** exceptions and interrupts handing ******/
|
||||
/****** entry for exception handling ******/
|
||||
.global exc_entry_cpu
|
||||
.align 4
|
||||
exc_entry_cpu:
|
||||
|
||||
EXCEPTION_PROLOGUE
|
||||
|
||||
mov blink, sp
|
||||
mov r3, sp /* as exception handler's para(p_excinfo) */
|
||||
|
||||
ld r0, [g_exc_nest_count]
|
||||
add r1, r0, 1
|
||||
st r1, [g_exc_nest_count]
|
||||
brne r0, 0, exc_handler_1
|
||||
/* change to exception stack if interrupt happened in task context */
|
||||
mov sp, _e_stack
|
||||
exc_handler_1:
|
||||
PUSH blink
|
||||
|
||||
jl tos_knl_irq_enter
|
||||
|
||||
lr r0, [AUX_ECR]
|
||||
lsr r0, r0, 16
|
||||
mov r1, exc_int_handler_table
|
||||
ld.as r2, [r1, r0]
|
||||
|
||||
mov r0, r3
|
||||
jl [r2]
|
||||
|
||||
jl tos_knl_irq_leave
|
||||
|
||||
/* interrupts are not allowed */
|
||||
ret_exc:
|
||||
POP sp
|
||||
mov r1, g_exc_nest_count
|
||||
ld r0, [r1]
|
||||
sub r0, r0, 1
|
||||
st r0, [r1]
|
||||
brne r0, 0, ret_exc_1 /* nest exception case */
|
||||
lr r1, [AUX_IRQ_ACT] /* nest interrupt case */
|
||||
brne r1, 0, ret_exc_1
|
||||
|
||||
ld r0, [g_context_switch_reqflg]
|
||||
brne r0, 0, ret_exc_2
|
||||
ret_exc_1: /* return from non-task context, interrupts or exceptions are nested */
|
||||
EXCEPTION_EPILOGUE
|
||||
rtie
|
||||
|
||||
/* there is a dispatch request */
|
||||
ret_exc_2:
|
||||
/* clear dispatch request */
|
||||
mov r0, 0
|
||||
st r0, [g_context_switch_reqflg]
|
||||
|
||||
SAVE_CALLEE_REGS /* save callee save registers */
|
||||
|
||||
/* clear exception bit to do exception exit by SW */
|
||||
lr r0, [AUX_STATUS32]
|
||||
bclr r0, r0, AUX_STATUS_BIT_AE
|
||||
kflag r0
|
||||
|
||||
mov r1, ret_exc_r /* save return address */
|
||||
PUSH r1
|
||||
|
||||
ld r0, [k_curr_task]
|
||||
ld r1, [k_next_task]
|
||||
b dispatcher
|
||||
|
||||
ret_exc_r:
|
||||
/* recover exception status */
|
||||
lr r0, [AUX_STATUS32]
|
||||
bset r0, r0, AUX_STATUS_BIT_AE
|
||||
kflag r0
|
||||
|
||||
RESTORE_CALLEE_REGS
|
||||
EXCEPTION_EPILOGUE
|
||||
rtie
|
||||
|
||||
/****** entry for normal interrupt exception handling ******/
|
||||
.global exc_entry_int /* entry for interrupt handling */
|
||||
.align 4
|
||||
exc_entry_int:
|
||||
#if ARC_FEATURE_FIRQ == 1
|
||||
/* check whether it is P0 interrupt */
|
||||
#if ARC_FEATURE_RGF_NUM_BANKS > 1
|
||||
lr r0, [AUX_IRQ_ACT]
|
||||
btst r0, 0
|
||||
jnz exc_entry_firq
|
||||
#else
|
||||
PUSH r10
|
||||
lr r10, [AUX_IRQ_ACT]
|
||||
btst r10, 0
|
||||
POP r10
|
||||
jnz exc_entry_firq
|
||||
#endif
|
||||
#endif
|
||||
INTERRUPT_PROLOGUE
|
||||
|
||||
mov blink, sp
|
||||
|
||||
clri /* disable interrupt */
|
||||
ld r3, [g_exc_nest_count]
|
||||
add r2, r3, 1
|
||||
st r2, [g_exc_nest_count]
|
||||
seti /* enable higher priority interrupt */
|
||||
|
||||
brne r3, 0, irq_handler_1
|
||||
/* change to exception stack if interrupt happened in task context */
|
||||
mov sp, _e_stack
|
||||
#if ARC_FEATURE_STACK_CHECK
|
||||
#if ARC_FEATURE_SEC_PRESENT
|
||||
lr r0, [AUX_SEC_STAT]
|
||||
bclr r0, r0, AUX_SEC_STAT_BIT_SSC
|
||||
sflag r0
|
||||
#else
|
||||
lr r0, [AUX_STATUS32]
|
||||
bclr r0, r0, AUX_STATUS_BIT_SC
|
||||
kflag r0
|
||||
#endif
|
||||
#endif
|
||||
irq_handler_1:
|
||||
PUSH blink
|
||||
|
||||
jl tos_knl_irq_enter
|
||||
|
||||
lr r0, [AUX_IRQ_CAUSE]
|
||||
sr r0, [AUX_IRQ_SELECT]
|
||||
mov r1, exc_int_handler_table
|
||||
ld.as r2, [r1, r0] /* r2 = exc_int_handler_table + irqno *4 */
|
||||
/* handle software triggered interrupt */
|
||||
lr r3, [AUX_IRQ_HINT]
|
||||
cmp r3, r0
|
||||
bne.d irq_hint_handled
|
||||
xor r3, r3, r3
|
||||
sr r3, [AUX_IRQ_HINT]
|
||||
irq_hint_handled:
|
||||
lr r3, [AUX_IRQ_PRIORITY]
|
||||
PUSH r3 /* save irq priority */
|
||||
|
||||
jl [r2] /* jump to interrupt handler */
|
||||
|
||||
jl tos_knl_irq_leave
|
||||
|
||||
ret_int:
|
||||
clri /* disable interrupt */
|
||||
POP r3 /* irq priority */
|
||||
POP sp
|
||||
mov r1, g_exc_nest_count
|
||||
ld r0, [r1]
|
||||
sub r0, r0, 1
|
||||
st r0, [r1]
|
||||
/* if there are multi-bits set in IRQ_ACT, it's still in nest interrupt */
|
||||
lr r0, [AUX_IRQ_CAUSE]
|
||||
sr r0, [AUX_IRQ_SELECT]
|
||||
lr r3, [AUX_IRQ_PRIORITY]
|
||||
lr r1, [AUX_IRQ_ACT]
|
||||
bclr r2, r1, r3
|
||||
brne r2, 0, ret_int_1
|
||||
|
||||
ld r0, [g_context_switch_reqflg]
|
||||
brne r0, 0, ret_int_2
|
||||
ret_int_1: /* return from non-task context */
|
||||
INTERRUPT_EPILOGUE
|
||||
rtie
|
||||
/* there is a dispatch request */
|
||||
ret_int_2:
|
||||
/* clear dispatch request */
|
||||
mov r0, 0
|
||||
st r0, [g_context_switch_reqflg]
|
||||
|
||||
/* interrupt return by SW */
|
||||
lr r10, [AUX_IRQ_ACT]
|
||||
PUSH r10
|
||||
bclr r10, r10, r3 /* clear related bits in IRQ_ACT */
|
||||
sr r10, [AUX_IRQ_ACT]
|
||||
|
||||
SAVE_CALLEE_REGS /* save callee save registers */
|
||||
mov r1, ret_int_r /* save return address */
|
||||
PUSH r1
|
||||
|
||||
ld r0, [k_curr_task]
|
||||
ld r1, [k_next_task]
|
||||
b dispatcher
|
||||
|
||||
ret_int_r:
|
||||
RESTORE_CALLEE_REGS
|
||||
/* recover AUX_IRQ_ACT to restore the interrup status */
|
||||
POPAX AUX_IRQ_ACT
|
||||
INTERRUPT_EPILOGUE
|
||||
rtie
|
||||
|
||||
/****** entry for fast irq exception handling ******/
|
||||
.global exc_entry_firq
|
||||
.align 4
|
||||
exc_entry_firq:
|
||||
SAVE_FIQ_EXC_REGS
|
||||
|
||||
jl tos_knl_irq_enter
|
||||
|
||||
lr r0, [AUX_IRQ_CAUSE]
|
||||
mov r1, exc_int_handler_table
|
||||
/* r2 = _kernel_exc_tbl + irqno *4 */
|
||||
ld.as r2, [r1, r0]
|
||||
|
||||
/* for the case of software triggered interrupt */
|
||||
lr r3, [AUX_IRQ_HINT]
|
||||
cmp r3, r0
|
||||
bne.d firq_hint_handled
|
||||
xor r3, r3, r3
|
||||
sr r3, [AUX_IRQ_HINT]
|
||||
firq_hint_handled:
|
||||
/* jump to interrupt handler */
|
||||
mov r0, sp
|
||||
jl [r2]
|
||||
|
||||
jl tos_knl_irq_leave
|
||||
|
||||
firq_return:
|
||||
RESTORE_FIQ_EXC_REGS
|
||||
rtie
|
||||
|
||||
/*
|
||||
* uint32_t port_cpu_clz(uint32_t val)
|
||||
* r0 --> val
|
||||
*/
|
||||
.global port_cpu_clz
|
||||
.align 4
|
||||
port_cpu_clz:
|
||||
breq r0, 0, cpu_clz_return
|
||||
fls r1, r0
|
||||
add r0, r1, 1
|
||||
cpu_clz_return:
|
||||
j [blink]
|
|
@ -0,0 +1,133 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_CPU_H_
|
||||
#define _TOS_CPU_H_
|
||||
|
||||
typedef struct cpu_context_st {
|
||||
cpu_data_t pc;
|
||||
cpu_data_t blink;
|
||||
cpu_data_t task;
|
||||
cpu_data_t status32;
|
||||
cpu_data_t r0;
|
||||
} cpu_context_t;
|
||||
|
||||
__API__ uint32_t tos_cpu_clz(uint32_t val);
|
||||
|
||||
__API__ void tos_cpu_int_disable(void);
|
||||
|
||||
__API__ void tos_cpu_int_enable(void);
|
||||
|
||||
__API__ cpu_cpsr_t tos_cpu_cpsr_save(void);
|
||||
|
||||
__API__ void tos_cpu_cpsr_restore(cpu_cpsr_t cpsr);
|
||||
|
||||
#if (TOS_CFG_CPU_HRTIMER_EN > 0u)
|
||||
|
||||
__API__ void tos_cpu_hrtimer_init(void);
|
||||
|
||||
__API__ cpu_hrtimer_t tos_cpu_hrtimer_read(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
__KNL__ void cpu_init(void);
|
||||
|
||||
|
||||
__KNL__ void cpu_reset(void);
|
||||
|
||||
|
||||
__KNL__ void cpu_systick_init(k_cycle_t cycle_per_tick);
|
||||
|
||||
|
||||
__KNL__ void cpu_sched_start(void);
|
||||
|
||||
|
||||
__KNL__ void cpu_context_switch(void);
|
||||
|
||||
|
||||
__KNL__ void cpu_irq_context_switch(void);
|
||||
|
||||
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
|
||||
|
||||
|
||||
__KNL__ k_err_t cpu_task_stack_draught_depth(k_stack_t *stk_base, size_t stk_size, int *depth);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
__KNL__ k_stack_t *cpu_task_stk_init(void *entry,
|
||||
void *arg,
|
||||
void *exit,
|
||||
k_stack_t *stk_base,
|
||||
size_t stk_size);
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN > 0u
|
||||
|
||||
|
||||
__KNL__ void cpu_systick_resume(void);
|
||||
|
||||
|
||||
__KNL__ void cpu_systick_suspend(void);
|
||||
|
||||
|
||||
__KNL__ void cpu_systick_reload_reset(void);
|
||||
|
||||
|
||||
__KNL__ void cpu_systick_pending_reset(void);
|
||||
|
||||
|
||||
__KNL__ k_time_t cpu_systick_max_delay_millisecond(void);
|
||||
|
||||
|
||||
__KNL__ void cpu_systick_expires_set(k_time_t millisecond);
|
||||
|
||||
|
||||
__KNL__ void cpu_systick_reset(void);
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
|
||||
__KNL__ void cpu_sleep_mode_enter(void);
|
||||
|
||||
|
||||
__KNL__ void cpu_stop_mode_enter(void);
|
||||
|
||||
|
||||
__KNL__ void cpu_standby_mode_enter(void);
|
||||
|
||||
#endif
|
||||
|
||||
/* Allocates CPU status register word. */
|
||||
#define TOS_CPU_CPSR_ALLOC() cpu_cpsr_t cpu_cpsr = (cpu_cpsr_t)0u
|
||||
|
||||
/* Save CPU status word & disable interrupts.*/
|
||||
#define TOS_CPU_INT_DISABLE() \
|
||||
do { \
|
||||
cpu_cpsr = tos_cpu_cpsr_save(); \
|
||||
} while (0)
|
||||
|
||||
/* Restore CPU status word. */
|
||||
#define TOS_CPU_INT_ENABLE() \
|
||||
do { \
|
||||
tos_cpu_cpsr_restore(cpu_cpsr); \
|
||||
} while (0)
|
||||
|
||||
#endif /* _TOS_CPU_H_ */
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_CPU_DEF_H_
|
||||
#define _TOS_CPU_DEF_H_
|
||||
|
||||
enum CPU_WORD_SIZE {
|
||||
CPU_WORD_SIZE_08,
|
||||
CPU_WORD_SIZE_16,
|
||||
CPU_WORD_SIZE_32,
|
||||
CPU_WORD_SIZE_64,
|
||||
};
|
||||
|
||||
enum CPU_STK_GROWTH {
|
||||
CPU_STK_GROWTH_ASCENDING,
|
||||
CPU_STK_GROWTH_DESCENDING,
|
||||
};
|
||||
|
||||
#endif /* _TOS_CPU_DEF_H_ */
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_CPU_TYPES_H_
|
||||
#define _TOS_CPU_TYPES_H_
|
||||
|
||||
/* CPU address type based on address bus size. */
|
||||
#if (TOS_CFG_CPU_ADDR_SIZE == CPU_WORD_SIZE_32)
|
||||
typedef uint32_t cpu_addr_t;
|
||||
#elif (TOS_CFG_CPU_ADDR_SIZE == CPU_WORD_SIZE_16)
|
||||
typedef uint16_t cpu_addr_t;
|
||||
#else
|
||||
typedef uint8_t cpu_addr_t;
|
||||
#endif
|
||||
|
||||
/* CPU data type based on data bus size. */
|
||||
#if (TOS_CFG_CPU_DATA_SIZE == CPU_WORD_SIZE_32)
|
||||
typedef uint32_t cpu_data_t;
|
||||
#elif (TOS_CFG_CPU_DATA_SIZE == CPU_WORD_SIZE_16)
|
||||
typedef uint16_t cpu_data_t;
|
||||
#else
|
||||
typedef uint8_t cpu_data_t;
|
||||
#endif
|
||||
|
||||
#if (TOS_CFG_CPU_HRTIMER_EN > 0)
|
||||
#if (TOS_CFG_CPU_HRTIMER_SIZE == CPU_WORD_SIZE_08)
|
||||
typedef uint8_t cpu_hrtimer_t;
|
||||
#elif (TOS_CFG_CPU_HRTIMER_SIZE == CPU_WORD_SIZE_16)
|
||||
typedef uint16_t cpu_hrtimer_t;
|
||||
#elif (TOS_CFG_CPU_HRTIMER_SIZE == CPU_WORD_SIZE_64)
|
||||
typedef uint64_t cpu_hrtimer_t;
|
||||
#else
|
||||
typedef uint32_t cpu_hrtimer_t;
|
||||
#endif
|
||||
#else
|
||||
typedef uint32_t cpu_hrtimer_t;
|
||||
#endif
|
||||
|
||||
//typedef cpu_addr_t size_t;
|
||||
typedef cpu_addr_t cpu_cpsr_t;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_FAULT_H_
|
||||
#define _TOS_FAULT_H_
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
|
||||
#error "unsupport now"
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _TOS_FAULT_H_ */
|
||||
|
|
@ -0,0 +1,266 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include <tos_k.h>
|
||||
#include "embARC.h"
|
||||
|
||||
void tos_cpu_tick_handler(void)
|
||||
{
|
||||
arc_timer_int_clear(BOARD_OS_TIMER_ID);
|
||||
tos_tick_handler();
|
||||
}
|
||||
|
||||
__API__ uint32_t tos_cpu_clz(uint32_t val)
|
||||
{
|
||||
#if defined(TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT) && (TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT == 0u)
|
||||
uint32_t nbr_lead_zeros = 0;
|
||||
|
||||
if (!(val & 0XFFFF0000)) {
|
||||
val <<= 16;
|
||||
nbr_lead_zeros += 16;
|
||||
}
|
||||
|
||||
if (!(val & 0XFF000000)) {
|
||||
val <<= 8;
|
||||
nbr_lead_zeros += 8;
|
||||
}
|
||||
|
||||
if (!(val & 0XF0000000)) {
|
||||
val <<= 4;
|
||||
nbr_lead_zeros += 4;
|
||||
}
|
||||
|
||||
if (!(val & 0XC0000000)) {
|
||||
val <<= 2;
|
||||
nbr_lead_zeros += 2;
|
||||
}
|
||||
|
||||
if (!(val & 0X80000000)) {
|
||||
nbr_lead_zeros += 1;
|
||||
}
|
||||
|
||||
if (!val) {
|
||||
nbr_lead_zeros += 1;
|
||||
}
|
||||
|
||||
return (nbr_lead_zeros);
|
||||
#else
|
||||
return (32 - port_cpu_clz(val));
|
||||
#endif
|
||||
}
|
||||
|
||||
__API__ void tos_cpu_int_disable(void)
|
||||
{
|
||||
arc_lock();
|
||||
}
|
||||
|
||||
__API__ void tos_cpu_int_enable(void)
|
||||
{
|
||||
arc_unlock();
|
||||
}
|
||||
|
||||
__API__ cpu_cpsr_t tos_cpu_cpsr_save(void)
|
||||
{
|
||||
return (cpu_cpsr_t)arc_lock_save();
|
||||
}
|
||||
|
||||
__API__ void tos_cpu_cpsr_restore(cpu_cpsr_t cpsr)
|
||||
{
|
||||
arc_unlock_restore(cpsr);
|
||||
}
|
||||
|
||||
__KNL__ void cpu_init(void)
|
||||
{
|
||||
k_cpu_cycle_per_tick = TOS_CFG_CPU_CLOCK / k_cpu_tick_per_second;
|
||||
cpu_systick_init(k_cpu_cycle_per_tick);
|
||||
|
||||
#if (TOS_CFG_CPU_HRTIMER_EN > 0)
|
||||
tos_cpu_hrtimer_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
__KNL__ void cpu_reset(void)
|
||||
{
|
||||
port_cpu_reset();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_sched_start(void)
|
||||
{
|
||||
port_sched_start();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_context_switch(void)
|
||||
{
|
||||
port_context_switch();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_irq_context_switch(void)
|
||||
{
|
||||
port_irq_context_switch();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_systick_init(k_cycle_t cycle_per_tick)
|
||||
{
|
||||
int_disable(BOARD_OS_TIMER_INTNO); /* disable os timer interrupt */
|
||||
arc_timer_stop(BOARD_OS_TIMER_ID);
|
||||
arc_timer_start(BOARD_OS_TIMER_ID, TIMER_CTRL_IE | TIMER_CTRL_NH, cycle_per_tick);
|
||||
|
||||
int_handler_install(BOARD_OS_TIMER_INTNO, (INT_HANDLER_T)tos_cpu_tick_handler);
|
||||
int_pri_set(BOARD_OS_TIMER_INTNO, INT_PRI_MIN + 1);
|
||||
int_enable(BOARD_OS_TIMER_INTNO);
|
||||
}
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN > 0u
|
||||
|
||||
/**
|
||||
* @brief Set value to systick reload value register
|
||||
*
|
||||
* @param cycles The value set to register
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__STATIC_INLINE__ void cpu_systick_reload(k_cycle_t cycle_per_tick)
|
||||
{
|
||||
port_systick_reload(cycle_per_tick);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable systick interrupt
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__KNL__ void cpu_systick_resume(void)
|
||||
{
|
||||
port_systick_resume();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable systick interrupt
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__KNL__ void cpu_systick_suspend(void)
|
||||
{
|
||||
port_systick_suspend();
|
||||
}
|
||||
|
||||
__KNL__ k_time_t cpu_systick_max_delay_millisecond(void)
|
||||
{
|
||||
return port_systick_max_delay_millisecond();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_systick_expires_set(k_time_t millisecond)
|
||||
{
|
||||
k_cycle_t cycles;
|
||||
|
||||
cycles = (k_cycle_t)((uint64_t)millisecond * TOS_CFG_CPU_CLOCK / K_TIME_MILLISEC_PER_SEC); /* CLOCK means cycle per second */
|
||||
|
||||
cpu_systick_reload(cycles - 12); /* interrupt delay */
|
||||
}
|
||||
|
||||
__KNL__ void cpu_systick_pending_reset(void)
|
||||
{
|
||||
port_systick_pending_reset();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_systick_reset(void)
|
||||
{
|
||||
cpu_systick_reload(k_cpu_cycle_per_tick);
|
||||
}
|
||||
|
||||
#endif /* TOS_CFG_TICKLESS_EN */
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__KNL__ void cpu_sleep_mode_enter(void)
|
||||
{
|
||||
port_sleep_mode_enter();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_stop_mode_enter(void)
|
||||
{
|
||||
port_stop_mode_enter();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_standby_mode_enter(void)
|
||||
{
|
||||
port_standby_mode_enter();
|
||||
}
|
||||
|
||||
#endif /* TOS_CFG_PWR_MGR_EN */
|
||||
|
||||
uint32_t g_context_switch_reqflg;
|
||||
uint32_t g_exc_nest_count;
|
||||
extern void start_r(void);
|
||||
|
||||
#if ARC_FEATURE_STACK_CHECK
|
||||
#define ARC_INIT_STATUS ((1 << AUX_STATUS_BIT_SC) | AUX_STATUS_MASK_IE | ((-1 - INT_PRI_MIN) << 1) | STATUS32_RESET_VALUE)
|
||||
#else
|
||||
#define ARC_INIT_STATUS (AUX_STATUS_MASK_IE | ((-1 - INT_PRI_MIN) << 1) | STATUS32_RESET_VALUE)
|
||||
#endif
|
||||
|
||||
__KNL__ k_stack_t *cpu_task_stk_init(void *entry,
|
||||
void *arg,
|
||||
void *exit,
|
||||
k_stack_t *stk_base,
|
||||
size_t stk_size)
|
||||
{
|
||||
cpu_data_t *sp;
|
||||
cpu_context_t *regs = 0;
|
||||
|
||||
sp = (cpu_data_t *)&stk_base[stk_size];
|
||||
sp = (cpu_data_t *)((cpu_addr_t)sp & 0xFFFFFFFC);
|
||||
sp -= (sizeof(cpu_context_t)/sizeof(cpu_data_t));
|
||||
regs = (cpu_context_t*) sp;
|
||||
|
||||
regs->pc = (cpu_data_t)start_r;
|
||||
regs->blink = (cpu_data_t)exit;
|
||||
regs->task = (cpu_data_t)entry;
|
||||
regs->status32 = ARC_INIT_STATUS;
|
||||
regs->r0 = (cpu_data_t)arg;
|
||||
|
||||
return (k_stack_t *)sp;
|
||||
}
|
||||
|
||||
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
|
||||
|
||||
__KNL__ k_err_t cpu_task_stack_draught_depth(k_stack_t *stk_base, size_t stk_size, int *depth)
|
||||
{
|
||||
uint8_t *slot;
|
||||
uint8_t *sp, *bp;
|
||||
int the_depth = 0;
|
||||
|
||||
bp = (uint8_t *)&stk_base[0];
|
||||
|
||||
sp = &stk_base[stk_size];
|
||||
sp = (uint8_t *)((cpu_addr_t)sp & 0xFFFFFFF8);
|
||||
|
||||
for (slot = sp - 1; slot >= bp; --slot) {
|
||||
if (*slot != 0xCC) {
|
||||
the_depth = sp - slot;
|
||||
}
|
||||
}
|
||||
|
||||
*depth = the_depth;
|
||||
if (the_depth == stk_size) {
|
||||
return K_ERR_TASK_STK_OVERFLOW;
|
||||
}
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,56 @@
|
|||
/* ------------------------------------------
|
||||
* Copyright (c) 2020, Synopsys, Inc. All rights reserved.
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
|
||||
* 1) Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
|
||||
* 3) Neither the name of the Synopsys, Inc., 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.
|
||||
*
|
||||
--------------------------------------------- */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cmsis_os.h"
|
||||
#include "embARC.h"
|
||||
#include "embARC_debug.h"
|
||||
|
||||
#define APPLICATION_TASK_STK_SIZE 1024
|
||||
extern void application_entry(void *arg);
|
||||
osThreadDef(application_entry, osPriorityNormal, 1, APPLICATION_TASK_STK_SIZE);
|
||||
|
||||
EMBARC_WEAK void application_entry(void *arg)
|
||||
{
|
||||
while (1) {
|
||||
printf("This is a demo task,please use your task entry!\r\n");
|
||||
tos_task_delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* OS kernel initialization */
|
||||
osKernelInitialize();
|
||||
/* application initialization entry */
|
||||
osThreadCreate(osThread(application_entry), NULL);
|
||||
/* start kernel */
|
||||
osKernelStart();
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_CPU_H_
|
||||
#define _TOS_CPU_H_
|
||||
|
||||
typedef struct cpu_context_st {
|
||||
cpu_data_t _R4;
|
||||
cpu_data_t _R5;
|
||||
cpu_data_t _R6;
|
||||
cpu_data_t _R7;
|
||||
cpu_data_t _R8;
|
||||
cpu_data_t _R9;
|
||||
cpu_data_t _R10;
|
||||
cpu_data_t _R11;
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
cpu_data_t EXC_RETURN;
|
||||
#endif
|
||||
cpu_data_t _R0;
|
||||
cpu_data_t _R1;
|
||||
cpu_data_t _R2;
|
||||
cpu_data_t _R3;
|
||||
cpu_data_t _R12;
|
||||
cpu_data_t _R14;
|
||||
cpu_data_t _PC;
|
||||
cpu_data_t _xPSR;
|
||||
} cpu_context_t;
|
||||
|
||||
__API__ uint32_t tos_cpu_clz(uint32_t val);
|
||||
|
||||
__API__ void tos_cpu_int_disable(void);
|
||||
|
||||
__API__ void tos_cpu_int_enable(void);
|
||||
|
||||
__API__ cpu_cpsr_t tos_cpu_cpsr_save(void);
|
||||
|
||||
__API__ void tos_cpu_cpsr_restore(cpu_cpsr_t cpsr);
|
||||
|
||||
#if (TOS_CFG_CPU_HRTIMER_EN > 0u)
|
||||
|
||||
__API__ void tos_cpu_hrtimer_init(void);
|
||||
|
||||
__API__ cpu_hrtimer_t tos_cpu_hrtimer_read(void);
|
||||
|
||||
#endif
|
||||
|
||||
__KNL__ void cpu_init(void);
|
||||
|
||||
__KNL__ void cpu_reset(void);
|
||||
|
||||
__KNL__ void cpu_systick_init(k_cycle_t cycle_per_tick);
|
||||
|
||||
__KNL__ void cpu_sched_start(void);
|
||||
|
||||
__KNL__ void cpu_context_switch(void);
|
||||
|
||||
__KNL__ void cpu_irq_context_switch(void);
|
||||
|
||||
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
|
||||
|
||||
__KNL__ k_err_t cpu_task_stack_draught_depth(k_stack_t *stk_base, size_t stk_size, int *depth);
|
||||
|
||||
#endif
|
||||
|
||||
__KNL__ k_stack_t *cpu_task_stk_init(void *entry,
|
||||
void *arg,
|
||||
void *exit,
|
||||
k_stack_t *stk_base,
|
||||
size_t stk_size);
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN > 0u
|
||||
|
||||
__KNL__ void cpu_systick_resume(void);
|
||||
|
||||
__KNL__ void cpu_systick_suspend(void);
|
||||
|
||||
__KNL__ void cpu_systick_reload_reset(void);
|
||||
|
||||
__KNL__ void cpu_systick_pending_reset(void);
|
||||
|
||||
__KNL__ k_time_t cpu_systick_max_delay_millisecond(void);
|
||||
|
||||
__KNL__ void cpu_systick_expires_set(k_time_t millisecond);
|
||||
|
||||
__KNL__ void cpu_systick_reset(void);
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__KNL__ void cpu_sleep_mode_enter(void);
|
||||
|
||||
__KNL__ void cpu_stop_mode_enter(void);
|
||||
|
||||
__KNL__ void cpu_standby_mode_enter(void);
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
|
||||
__KNL__ void cpu_flush_fpu(void);
|
||||
|
||||
#endif /* TOS_CFG_CPU_ARM_FPU_EN */
|
||||
|
||||
__KNL__ void cpu_fault_diagnosis(void);
|
||||
|
||||
#endif
|
||||
|
||||
/* Allocates CPU status register word. */
|
||||
#define TOS_CPU_CPSR_ALLOC() cpu_cpsr_t cpu_cpsr = (cpu_cpsr_t)0u
|
||||
|
||||
/* Save CPU status word & disable interrupts.*/
|
||||
#define TOS_CPU_INT_DISABLE() \
|
||||
do { \
|
||||
cpu_cpsr = tos_cpu_cpsr_save(); \
|
||||
} while (0)
|
||||
|
||||
/* Restore CPU status word. */
|
||||
#define TOS_CPU_INT_ENABLE() \
|
||||
do { \
|
||||
tos_cpu_cpsr_restore(cpu_cpsr); \
|
||||
} while (0)
|
||||
|
||||
#endif /* _TOS_CPU_H_ */
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_CPU_DEF_H_
|
||||
#define _TOS_CPU_DEF_H_
|
||||
|
||||
#define CPU_WORD_SIZE_08 1
|
||||
#define CPU_WORD_SIZE_16 2
|
||||
#define CPU_WORD_SIZE_32 3
|
||||
#define CPU_WORD_SIZE_64 4
|
||||
|
||||
#define CPU_STK_GROWTH_ASCENDING 1
|
||||
#define CPU_STK_GROWTH_DESCENDING 2
|
||||
|
||||
#define CPU_BYTE_ORDER_LITTLE_ENDIAN 1
|
||||
#define CPU_BYTE_ORDER_BIG_ENDIAN 2
|
||||
|
||||
#endif /* _TOS_CPU_DEF_H_ */
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_CPU_TYPES_H_
|
||||
#define _TOS_CPU_TYPES_H_
|
||||
|
||||
/* CPU address type based on address bus size. */
|
||||
#if (TOS_CFG_CPU_ADDR_SIZE == CPU_WORD_SIZE_32)
|
||||
typedef uint32_t cpu_addr_t;
|
||||
#elif (TOS_CFG_CPU_ADDR_SIZE == CPU_WORD_SIZE_16)
|
||||
typedef uint16_t cpu_addr_t;
|
||||
#else
|
||||
typedef uint8_t cpu_addr_t;
|
||||
#endif
|
||||
|
||||
/* CPU data type based on data bus size. */
|
||||
#if (TOS_CFG_CPU_DATA_SIZE == CPU_WORD_SIZE_32)
|
||||
typedef uint32_t cpu_data_t;
|
||||
#elif (TOS_CFG_CPU_DATA_SIZE == CPU_WORD_SIZE_16)
|
||||
typedef uint16_t cpu_data_t;
|
||||
#else
|
||||
typedef uint8_t cpu_data_t;
|
||||
#endif
|
||||
|
||||
#if (TOS_CFG_CPU_HRTIMER_EN > 0)
|
||||
#if (TOS_CFG_CPU_HRTIMER_SIZE == CPU_WORD_SIZE_08)
|
||||
typedef uint8_t cpu_hrtimer_t;
|
||||
#elif (TOS_CFG_CPU_HRTIMER_SIZE == CPU_WORD_SIZE_16)
|
||||
typedef uint16_t cpu_hrtimer_t;
|
||||
#elif (TOS_CFG_CPU_HRTIMER_SIZE == CPU_WORD_SIZE_64)
|
||||
typedef uint64_t cpu_hrtimer_t;
|
||||
#else
|
||||
typedef uint32_t cpu_hrtimer_t;
|
||||
#endif
|
||||
#else
|
||||
typedef uint32_t cpu_hrtimer_t;
|
||||
#endif
|
||||
|
||||
typedef cpu_addr_t cpu_cpsr_t;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_FAULT_H_
|
||||
#define _TOS_FAULT_H_
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
|
||||
typedef int (*k_fault_log_writer_t)(const char *format, ...);
|
||||
|
||||
#define K_FAULT_STACK_DUMP_DEPTH 10u
|
||||
|
||||
#define K_FAULT_CALL_STACK_BACKTRACE_DEPTH 5u
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
typedef struct fault_fpu_frame_st {
|
||||
cpu_data_t s0;
|
||||
cpu_data_t s1;
|
||||
cpu_data_t s2;
|
||||
cpu_data_t s3;
|
||||
cpu_data_t s4;
|
||||
cpu_data_t s5;
|
||||
cpu_data_t s6;
|
||||
cpu_data_t s7;
|
||||
cpu_data_t s8;
|
||||
cpu_data_t s9;
|
||||
cpu_data_t s10;
|
||||
cpu_data_t s11;
|
||||
cpu_data_t s12;
|
||||
cpu_data_t s13;
|
||||
cpu_data_t s14;
|
||||
cpu_data_t s15;
|
||||
cpu_data_t fpscr;
|
||||
} fault_fpu_frame_t;
|
||||
#endif
|
||||
|
||||
typedef struct fault_cpu_frame_st {
|
||||
cpu_data_t r0;
|
||||
cpu_data_t r1;
|
||||
cpu_data_t r2;
|
||||
cpu_data_t r3;
|
||||
cpu_data_t r12;
|
||||
cpu_data_t lr;
|
||||
cpu_data_t pc;
|
||||
cpu_data_t spsr;
|
||||
} fault_cpu_frame_t;
|
||||
|
||||
typedef struct fault_exc_frame_st {
|
||||
fault_cpu_frame_t cpu_frame;
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
fault_fpu_frame_t fpu_frame;
|
||||
#endif
|
||||
} fault_exc_frame_t;
|
||||
|
||||
/**
|
||||
* information we need to do fault backtrace
|
||||
*/
|
||||
typedef struct fault_information_st {
|
||||
int is_thumb : 1; /**< whether it is thumb we use when we fall into fault? */
|
||||
int is_on_task : 1; /**< whether we are on a task when fall into fault? */
|
||||
int is_stk_ovrf : 1; /**< whether we get a stack overflow */
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
int is_ext_stk_frm : 1; /**< whether it is a extended stack frame?(whether the cpu has pushed fpu registers onto the stack) */
|
||||
#endif
|
||||
|
||||
cpu_addr_t pc; /**< just where fault happens */
|
||||
|
||||
cpu_addr_t sp_before_fault; /**< original sp just before the cpu push the fault exception frame */
|
||||
|
||||
/**
|
||||
* we need main_stack_start & main_stack_limit to do call stack backtrace
|
||||
* when we fall into fault during a task, we should do the call stack backtrace on the task's stack
|
||||
* but if not, which means we are in kernel, we should do the call stack backtrace on the main stack
|
||||
* in arm v7-m, this should be the MSP's start and limit
|
||||
* in arm v7-a, call stack backtrace is another story(much more elegant because we have FP).
|
||||
*/
|
||||
cpu_addr_t stack_start; /**< current sp start address we use. if on task, it'll be the task's stack, otherwise it'll be the msp */
|
||||
cpu_addr_t stack_limit; /**< current sp limit address */
|
||||
cpu_addr_t code_start; /**< current code start address */
|
||||
cpu_addr_t code_limit; /**< current code limit address */
|
||||
} fault_info_t;
|
||||
|
||||
#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
|
||||
|
||||
#define DEFAULT_CODE_SECTION_NAME ER_IROM1
|
||||
#define DEFAULT_CSTACK_SECTION_NAME STACK
|
||||
|
||||
#define SECTION_START(_name_) _name_##$$Base
|
||||
#define SECTION_END(_name_) _name_##$$Limit
|
||||
#define IMAGE_SECTION_START(_name_) Image$$##_name_##$$Base
|
||||
#define IMAGE_SECTION_END(_name_) Image$$##_name_##$$Limit
|
||||
#define CSTACK_BLOCK_START(_name_) SECTION_START(_name_)
|
||||
#define CSTACK_BLOCK_END(_name_) SECTION_END(_name_)
|
||||
#define CODE_SECTION_START(_name_) IMAGE_SECTION_START(_name_)
|
||||
#define CODE_SECTION_END(_name_) IMAGE_SECTION_END(_name_)
|
||||
|
||||
extern const int CSTACK_BLOCK_START(DEFAULT_CSTACK_SECTION_NAME);
|
||||
extern const int CSTACK_BLOCK_END(DEFAULT_CSTACK_SECTION_NAME);
|
||||
extern const int CODE_SECTION_START(DEFAULT_CODE_SECTION_NAME);
|
||||
extern const int CODE_SECTION_END(DEFAULT_CODE_SECTION_NAME);
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_code_start(void)
|
||||
{
|
||||
return (cpu_addr_t)&CODE_SECTION_START(DEFAULT_CODE_SECTION_NAME);
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_code_limit(void)
|
||||
{
|
||||
return (cpu_addr_t)&CODE_SECTION_END(DEFAULT_CODE_SECTION_NAME);
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_msp_start(void)
|
||||
{
|
||||
return (cpu_addr_t)&CSTACK_BLOCK_START(DEFAULT_CSTACK_SECTION_NAME);
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_msp_limit(void)
|
||||
{
|
||||
return (cpu_addr_t)&CSTACK_BLOCK_END(DEFAULT_CSTACK_SECTION_NAME);
|
||||
}
|
||||
|
||||
#elif defined(__ICCARM__)
|
||||
|
||||
#define DEFAULT_CODE_SECTION_NAME ".text"
|
||||
#define DEFAULT_CSTACK_SECTION_NAME "CSTACK"
|
||||
|
||||
#pragma section=DEFAULT_CSTACK_SECTION_NAME
|
||||
#pragma section=DEFAULT_CODE_SECTION_NAME
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_code_start(void)
|
||||
{
|
||||
return (cpu_addr_t)__section_begin(DEFAULT_CODE_SECTION_NAME);
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_code_limit(void)
|
||||
{
|
||||
return (cpu_addr_t)__section_end(DEFAULT_CODE_SECTION_NAME);
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_msp_start(void)
|
||||
{
|
||||
return (cpu_addr_t)__section_begin(DEFAULT_CSTACK_SECTION_NAME);
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_msp_limit(void)
|
||||
{
|
||||
return (cpu_addr_t)__section_end(DEFAULT_CSTACK_SECTION_NAME);
|
||||
}
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
/**
|
||||
* if we are using keil(armcc) or mdk(iccarm), we probably use the defult link script supplied by the IDE.
|
||||
* the way to locate the text/stack section start and limit is to find them in default link script.
|
||||
* but if we build our project by makefile(or something like scons, cmake, etc), we probably need to write
|
||||
* our own link scrpit, if so, we should do like this(just a demo):
|
||||
*
|
||||
_stext = .;
|
||||
.text : {
|
||||
*(.text.startup)
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
}
|
||||
_etext = .;
|
||||
|
||||
__bss_start = .;
|
||||
.bss : {
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(COMMON)
|
||||
_sstack = .;
|
||||
*(.cstack)
|
||||
_estack = .;
|
||||
}
|
||||
__bss_end = .;
|
||||
* by this, we can locate text/stack section start and limit by _stext/_etext and _sstack/_estack
|
||||
*/
|
||||
#define DEFAULT_CODE_SECTION_START _stext
|
||||
#define DEFAULT_CODE_SECTION_END _etext
|
||||
#define DEFAULT_CSTACK_SECTION_START _sstack
|
||||
#define DEFAULT_CSTACK_SECTION_END _estack
|
||||
|
||||
extern const int DEFAULT_CODE_SECTION_START;
|
||||
extern const int DEFAULT_CODE_SECTION_END;
|
||||
|
||||
extern const int DEFAULT_CSTACK_SECTION_START;
|
||||
extern const int DEFAULT_CSTACK_SECTION_END;
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_code_start(void)
|
||||
{
|
||||
return (cpu_addr_t)(&(DEFAULT_CODE_SECTION_START));
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_code_limit(void)
|
||||
{
|
||||
return (cpu_addr_t)(&(DEFAULT_CODE_SECTION_END));
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_msp_start(void)
|
||||
{
|
||||
return (cpu_addr_t)(&(DEFAULT_CSTACK_SECTION_START));
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_msp_limit(void)
|
||||
{
|
||||
return (cpu_addr_t)(&(DEFAULT_CSTACK_SECTION_END));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
__API__ void tos_fault_log_writer_set(k_fault_log_writer_t log_writer);
|
||||
|
||||
__KNL__ int fault_default_log_writer(const char *format, ...);
|
||||
|
||||
__KNL__ void fault_backtrace(cpu_addr_t lr, fault_exc_frame_t *frame);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _TOS_FAULT_H_ */
|
||||
|
|
@ -0,0 +1,293 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos_k.h"
|
||||
|
||||
__API__ uint32_t tos_cpu_clz(uint32_t val)
|
||||
{
|
||||
#if defined(TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT) && (TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT == 0u)
|
||||
uint32_t nbr_lead_zeros = 0;
|
||||
|
||||
if (!(val & 0XFFFF0000)) {
|
||||
val <<= 16;
|
||||
nbr_lead_zeros += 16;
|
||||
}
|
||||
|
||||
if (!(val & 0XFF000000)) {
|
||||
val <<= 8;
|
||||
nbr_lead_zeros += 8;
|
||||
}
|
||||
|
||||
if (!(val & 0XF0000000)) {
|
||||
val <<= 4;
|
||||
nbr_lead_zeros += 4;
|
||||
}
|
||||
|
||||
if (!(val & 0XC0000000)) {
|
||||
val <<= 2;
|
||||
nbr_lead_zeros += 2;
|
||||
}
|
||||
|
||||
if (!(val & 0X80000000)) {
|
||||
nbr_lead_zeros += 1;
|
||||
}
|
||||
|
||||
if (!val) {
|
||||
nbr_lead_zeros += 1;
|
||||
}
|
||||
|
||||
return (nbr_lead_zeros);
|
||||
#else
|
||||
return port_clz(val);
|
||||
#endif
|
||||
}
|
||||
|
||||
__API__ void tos_cpu_int_disable(void)
|
||||
{
|
||||
port_int_disable();
|
||||
}
|
||||
|
||||
__API__ void tos_cpu_int_enable(void)
|
||||
{
|
||||
port_int_enable();
|
||||
}
|
||||
|
||||
__API__ cpu_cpsr_t tos_cpu_cpsr_save(void)
|
||||
{
|
||||
return port_cpsr_save();
|
||||
}
|
||||
|
||||
__API__ void tos_cpu_cpsr_restore(cpu_cpsr_t cpsr)
|
||||
{
|
||||
port_cpsr_restore(cpsr);
|
||||
}
|
||||
|
||||
__KNL__ void cpu_init(void)
|
||||
{
|
||||
k_cpu_cycle_per_tick = TOS_CFG_CPU_CLOCK / k_cpu_tick_per_second;
|
||||
cpu_systick_init(k_cpu_cycle_per_tick);
|
||||
|
||||
#if (TOS_CFG_CPU_HRTIMER_EN > 0)
|
||||
tos_cpu_hrtimer_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
__KNL__ void cpu_reset(void)
|
||||
{
|
||||
port_cpu_reset();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_sched_start(void)
|
||||
{
|
||||
port_sched_start();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_context_switch(void)
|
||||
{
|
||||
port_context_switch();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_irq_context_switch(void)
|
||||
{
|
||||
port_irq_context_switch();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_systick_init(k_cycle_t cycle_per_tick)
|
||||
{
|
||||
port_systick_priority_set(TOS_CFG_CPU_SYSTICK_PRIO);
|
||||
port_systick_config(cycle_per_tick);
|
||||
}
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN > 0u
|
||||
|
||||
/**
|
||||
* @brief Set value to systick reload value register
|
||||
*
|
||||
* @param cycles The value set to register
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__STATIC_INLINE__ void cpu_systick_reload(k_cycle_t cycle_per_tick)
|
||||
{
|
||||
port_systick_reload(cycle_per_tick);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable systick interrupt
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__KNL__ void cpu_systick_resume(void)
|
||||
{
|
||||
port_systick_resume();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable systick interrupt
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__KNL__ void cpu_systick_suspend(void)
|
||||
{
|
||||
port_systick_suspend();
|
||||
}
|
||||
|
||||
__KNL__ k_time_t cpu_systick_max_delay_millisecond(void)
|
||||
{
|
||||
return port_systick_max_delay_millisecond();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_systick_expires_set(k_time_t millisecond)
|
||||
{
|
||||
k_cycle_t cycles;
|
||||
|
||||
cycles = (k_cycle_t)((uint64_t)millisecond * TOS_CFG_CPU_CLOCK / K_TIME_MILLISEC_PER_SEC); /* CLOCK means cycle per second */
|
||||
|
||||
cpu_systick_reload(cycles - 12); /* interrupt delay */
|
||||
}
|
||||
|
||||
__KNL__ void cpu_systick_pending_reset(void)
|
||||
{
|
||||
port_systick_pending_reset();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_systick_reset(void)
|
||||
{
|
||||
cpu_systick_reload(k_cpu_cycle_per_tick);
|
||||
}
|
||||
|
||||
#endif /* TOS_CFG_TICKLESS_EN */
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__KNL__ void cpu_sleep_mode_enter(void)
|
||||
{
|
||||
port_sleep_mode_enter();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_stop_mode_enter(void)
|
||||
{
|
||||
port_stop_mode_enter();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_standby_mode_enter(void)
|
||||
{
|
||||
port_standby_mode_enter();
|
||||
}
|
||||
|
||||
#endif /* TOS_CFG_PWR_MGR_EN */
|
||||
|
||||
__KNL__ k_stack_t *cpu_task_stk_init(void *entry,
|
||||
void *arg,
|
||||
void *exit,
|
||||
k_stack_t *stk_base,
|
||||
size_t stk_size)
|
||||
{
|
||||
cpu_data_t *sp;
|
||||
|
||||
sp = (cpu_data_t *)&stk_base[stk_size];
|
||||
sp = (cpu_data_t *)((cpu_addr_t)sp & 0xFFFFFFF8);
|
||||
|
||||
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
|
||||
uint8_t *slot = (uint8_t *)&stk_base[0];
|
||||
for (; slot < (uint8_t *)sp; ++slot) {
|
||||
*slot = 0xCC;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* auto-saved on exception(pendSV) by hardware */
|
||||
*--sp = (cpu_data_t)0x01000000u; /* xPSR */
|
||||
*--sp = (cpu_data_t)entry; /* entry */
|
||||
*--sp = (cpu_data_t)exit; /* R14 (LR) */
|
||||
*--sp = (cpu_data_t)0x12121212u; /* R12 */
|
||||
*--sp = (cpu_data_t)0x03030303u; /* R3 */
|
||||
*--sp = (cpu_data_t)0x02020202u; /* R2 */
|
||||
*--sp = (cpu_data_t)0x01010101u; /* R1 */
|
||||
*--sp = (cpu_data_t)arg; /* R0: arg */
|
||||
|
||||
/* Remaining registers saved on process stack */
|
||||
/* EXC_RETURN = 0xFFFFFFFDL
|
||||
Initial state: Thread mode + non-floating-point state + PSP
|
||||
31 - 28 : EXC_RETURN flag, 0xF
|
||||
27 - 5 : reserved, 0xFFFFFE
|
||||
4 : 1, basic stack frame; 0, extended stack frame
|
||||
3 : 1, return to Thread mode; 0, return to Handler mode
|
||||
2 : 1, return to PSP; 0, return to MSP
|
||||
1 : reserved, 0
|
||||
0 : reserved, 1
|
||||
*/
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
*--sp = (cpu_data_t)0xFFFFFFFDL;
|
||||
#endif
|
||||
|
||||
*--sp = (cpu_data_t)0x11111111u; /* R11 */
|
||||
*--sp = (cpu_data_t)0x10101010u; /* R10 */
|
||||
*--sp = (cpu_data_t)0x09090909u; /* R9 */
|
||||
*--sp = (cpu_data_t)0x08080808u; /* R8 */
|
||||
*--sp = (cpu_data_t)0x07070707u; /* R7 */
|
||||
*--sp = (cpu_data_t)0x06060606u; /* R6 */
|
||||
*--sp = (cpu_data_t)0x05050505u; /* R5 */
|
||||
*--sp = (cpu_data_t)0x04040404u; /* R4 */
|
||||
|
||||
return (k_stack_t *)sp;
|
||||
}
|
||||
|
||||
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
|
||||
|
||||
__KNL__ k_err_t cpu_task_stack_draught_depth(k_stack_t *stk_base, size_t stk_size, int *depth)
|
||||
{
|
||||
uint8_t *slot;
|
||||
uint8_t *sp, *bp;
|
||||
int the_depth = 0;
|
||||
|
||||
bp = (uint8_t *)&stk_base[0];
|
||||
|
||||
sp = &stk_base[stk_size];
|
||||
sp = (uint8_t *)((cpu_addr_t)sp & 0xFFFFFFF8);
|
||||
|
||||
for (slot = sp - 1; slot >= bp; --slot) {
|
||||
if (*slot != 0xCC) {
|
||||
the_depth = sp - slot;
|
||||
}
|
||||
}
|
||||
|
||||
*depth = the_depth;
|
||||
if (the_depth == stk_size) {
|
||||
return K_ERR_TASK_STK_OVERFLOW;
|
||||
}
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
__KNL__ void cpu_flush_fpu(void)
|
||||
{
|
||||
(void)__get_FPSCR();
|
||||
}
|
||||
#endif
|
||||
|
||||
__KNL__ void cpu_fault_diagnosis(void)
|
||||
{
|
||||
port_fault_diagnosis();
|
||||
}
|
||||
|
||||
#endif /* TOS_CFG_FAULT_BACKTRACE_EN */
|
||||
|
|
@ -0,0 +1,268 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos_k.h"
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
|
||||
__STATIC_INLINE__ void fault_spin(void)
|
||||
{
|
||||
tos_knl_sched_lock();
|
||||
tos_cpu_int_disable();
|
||||
while (K_TRUE) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/* EXC_RETURN:
|
||||
31 - 28 : EXC_RETURN flag
|
||||
27 - 5 : reserved
|
||||
4 : 1, basic stack frame; 0, extended stack frame
|
||||
3 : 1, return to Thread mode; 0, return to Handler mode
|
||||
2 : 1, return to PSP; 0, return to MSP
|
||||
1 : reserved, 0
|
||||
0 : reserved, 1
|
||||
*/
|
||||
__STATIC_INLINE__ int fault_is_on_task(cpu_data_t lr)
|
||||
{
|
||||
return (lr & (1u << 2)) != 0;
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ int fault_is_thumb(cpu_data_t psr)
|
||||
{
|
||||
return (psr & (1u << 24)) != 0;
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ int fault_is_code(fault_info_t *info, cpu_data_t value)
|
||||
{
|
||||
return value >= info->code_start && value <= info->code_limit;
|
||||
}
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
__STATIC_INLINE__ int fault_is_extended_stack_frame(cpu_data_t lr)
|
||||
{
|
||||
return (lr & (1u << 4)) == 0;
|
||||
}
|
||||
|
||||
__STATIC__ void fault_dump_fpu_frame(fault_fpu_frame_t *fpu_frame)
|
||||
{
|
||||
/*
|
||||
* As known, v7-m has a feature named "LAZY PUSH", for the reason we do not do any float
|
||||
* operation in fault_backtrace, cpu will not do the real fpu register push to the stack.
|
||||
* that means the value we dump in fault_dump_fpu_frame will not be the correct value of
|
||||
* each FPU register.
|
||||
* We define a function here which access to FPSCR, if this function involved, cpu will do
|
||||
* the real FPU register push so we will get the correct dump.
|
||||
* I know it's ugly, but it works. If you know a better way, please tell me.
|
||||
*/
|
||||
cpu_flush_fpu();
|
||||
|
||||
k_fault_log_writer("\n\n====================== FPU Registers =======================\n");
|
||||
k_fault_log_writer(" %s: %08x\n", "FPSCR", fpu_frame->fpscr);
|
||||
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||
"S0 ", fpu_frame->s0,
|
||||
"S1 ", fpu_frame->s1,
|
||||
"S2 ", fpu_frame->s2,
|
||||
"S3 ", fpu_frame->s3);
|
||||
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||
"S4 ", fpu_frame->s4,
|
||||
"S5 ", fpu_frame->s5,
|
||||
"S6 ", fpu_frame->s6,
|
||||
"S7 ", fpu_frame->s7);
|
||||
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||
"S8 ", fpu_frame->s8,
|
||||
"S9 ", fpu_frame->s9,
|
||||
"S10", fpu_frame->s10,
|
||||
"S11", fpu_frame->s11);
|
||||
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||
"S12", fpu_frame->s12,
|
||||
"S13", fpu_frame->s13,
|
||||
"S14", fpu_frame->s14,
|
||||
"S15", fpu_frame->s15);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
__STATIC__ void fault_dump_cpu_frame(fault_cpu_frame_t *cpu_frame)
|
||||
{
|
||||
k_fault_log_writer("\n\n====================== CPU Registers =======================\n");
|
||||
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||
"R0 ", cpu_frame->r0,
|
||||
"R1 ", cpu_frame->r1,
|
||||
"R2 ", cpu_frame->r2,
|
||||
"R3 ", cpu_frame->r3);
|
||||
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||
"R12", cpu_frame->r12,
|
||||
"LR ", cpu_frame->lr,
|
||||
"PC ", cpu_frame->pc,
|
||||
"PSR", cpu_frame->spsr);
|
||||
}
|
||||
|
||||
__STATIC__ void fault_dump_stack(fault_info_t *info, size_t depth)
|
||||
{
|
||||
cpu_addr_t sp = info->sp_before_fault;
|
||||
|
||||
k_fault_log_writer("\nTASK STACK DUMP:\n");
|
||||
while (sp <= info->stack_limit && depth--) {
|
||||
k_fault_log_writer(" addr: %08x data: %08x\n", sp, (cpu_data_t)*(cpu_data_t *)sp);
|
||||
sp += sizeof(cpu_addr_t);
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC__ void fault_call_stack_backtrace(fault_info_t *info, size_t depth)
|
||||
{
|
||||
cpu_data_t value;
|
||||
cpu_addr_t sp = info->sp_before_fault;
|
||||
|
||||
if (info->is_stk_ovrf) {
|
||||
return;
|
||||
}
|
||||
|
||||
k_fault_log_writer("\n\n====================== Dump Call Stack =====================\n");
|
||||
|
||||
k_fault_log_writer(" %x\n", info->pc);
|
||||
|
||||
/* walk through the stack, check every content on stack whether is a instruction(code) */
|
||||
for (; sp < info->stack_limit && depth; sp += sizeof(cpu_addr_t)) {
|
||||
value = *((cpu_addr_t *)sp) - sizeof(cpu_addr_t);
|
||||
|
||||
/* if thumb, a instruction's first bit must be 1 */
|
||||
if (info->is_thumb && !(value & 1)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fault_is_code(info, value)) {
|
||||
k_fault_log_writer(" %x\n", value);
|
||||
--depth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC__ void fault_dump_task(fault_info_t *info)
|
||||
{
|
||||
k_task_t *task;
|
||||
|
||||
if (!info->is_on_task) {
|
||||
return;
|
||||
}
|
||||
|
||||
task = k_curr_task;
|
||||
k_fault_log_writer("\n\n====================== Fault on task =======================\n");
|
||||
k_fault_log_writer(" TASK NAME: %s\n", task->name);
|
||||
k_fault_log_writer(" STK BASE: %x\n", info->stack_start);
|
||||
k_fault_log_writer(" STK SIZE: %x\n", task->stk_size * sizeof(k_stack_t));
|
||||
k_fault_log_writer(" STK LIMIT: %x\n", info->stack_limit);
|
||||
|
||||
if (!info->is_stk_ovrf) {
|
||||
fault_dump_stack(info, K_FAULT_STACK_DUMP_DEPTH);
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC__ void fault_dump_information(fault_info_t *info)
|
||||
{
|
||||
k_fault_log_writer("\n\n================== Dump Fault Information ==================\n");
|
||||
k_fault_log_writer(" THUMB: %s\n", info->is_thumb ? "TRUE" : "FALSE");
|
||||
k_fault_log_writer(" ON TASK: %s\n", info->is_on_task? "TRUE" : "FALSE");
|
||||
k_fault_log_writer(" STK OVRF: %s\n", info->is_stk_ovrf? "TRUE" : "FALSE");
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
k_fault_log_writer(" EXT STK: %s\n", info->is_ext_stk_frm? "TRUE" : "FALSE");
|
||||
#endif
|
||||
|
||||
k_fault_log_writer(" PC: %08x\n", info->pc);
|
||||
k_fault_log_writer(" SP: %08x\n", info->sp_before_fault);
|
||||
k_fault_log_writer(" STK START: %08x\n", info->stack_start);
|
||||
k_fault_log_writer(" STK LIMIT: %08x\n", info->stack_limit);
|
||||
k_fault_log_writer(" COD START: %08x\n", info->code_start);
|
||||
k_fault_log_writer(" COD LIMIT: %08x\n", info->code_limit);
|
||||
}
|
||||
|
||||
__STATIC__ void fault_gather_information(cpu_data_t lr, fault_exc_frame_t *frame, fault_info_t *info)
|
||||
{
|
||||
info->is_thumb = fault_is_thumb(frame->cpu_frame.spsr);
|
||||
info->is_on_task = fault_is_on_task(lr);
|
||||
|
||||
info->pc = frame->cpu_frame.pc;
|
||||
|
||||
info->sp_before_fault = (cpu_addr_t)frame + sizeof(fault_cpu_frame_t);
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
info->is_ext_stk_frm = fault_is_extended_stack_frame(lr);
|
||||
|
||||
if (info->is_ext_stk_frm) {
|
||||
info->sp_before_fault += sizeof(fault_fpu_frame_t);
|
||||
}
|
||||
#endif
|
||||
|
||||
info->code_start = fault_code_start();
|
||||
info->code_limit = fault_code_limit();
|
||||
|
||||
if (info->is_on_task) {
|
||||
info->stack_start = (cpu_addr_t)k_curr_task->stk_base;
|
||||
info->stack_limit = info->stack_start + k_curr_task->stk_size * sizeof(k_task_t);
|
||||
} else {
|
||||
info->stack_start = fault_msp_start();
|
||||
info->stack_limit = fault_msp_limit();
|
||||
}
|
||||
|
||||
info->is_stk_ovrf = (info->sp_before_fault < info->stack_start || info->sp_before_fault > info->stack_limit);
|
||||
}
|
||||
|
||||
__KNL__ int fault_default_log_writer(const char *format, ...)
|
||||
{
|
||||
int len;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
len = vprintf(format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
__API__ void tos_fault_log_writer_set(k_fault_log_writer_t log_writer)
|
||||
{
|
||||
k_fault_log_writer = log_writer;
|
||||
}
|
||||
|
||||
__KNL__ void fault_backtrace(cpu_addr_t lr, fault_exc_frame_t *frame)
|
||||
{
|
||||
fault_info_t info;
|
||||
|
||||
fault_gather_information(lr, frame, &info);
|
||||
|
||||
fault_dump_information(&info);
|
||||
|
||||
fault_dump_task(&info);
|
||||
|
||||
fault_dump_cpu_frame(&frame->cpu_frame);
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
if (info.is_ext_stk_frm) {
|
||||
fault_dump_fpu_frame(&frame->fpu_frame);
|
||||
}
|
||||
#endif
|
||||
|
||||
fault_call_stack_backtrace(&info, K_FAULT_CALL_STACK_BACKTRACE_DEPTH);
|
||||
|
||||
cpu_fault_diagnosis();
|
||||
|
||||
fault_spin();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _PORT_H_
|
||||
#define _PORT_H_
|
||||
|
||||
__PORT__ void port_int_disable(void);
|
||||
|
||||
__PORT__ void port_int_enable(void);
|
||||
|
||||
__PORT__ cpu_cpsr_t port_cpsr_save(void);
|
||||
|
||||
__PORT__ void port_cpsr_restore(cpu_cpsr_t cpsr);
|
||||
|
||||
__PORT__ void port_cpu_reset(void);
|
||||
|
||||
__PORT__ void port_sched_start(void) __NO_RETURN__;
|
||||
|
||||
__PORT__ void port_context_switch(void);
|
||||
|
||||
__PORT__ void port_irq_context_switch(void);
|
||||
|
||||
__PORT__ void port_systick_config(uint32_t cycle_per_tick);
|
||||
|
||||
__PORT__ void port_systick_priority_set(uint32_t prio);
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN > 0u
|
||||
|
||||
__PORT__ void port_systick_resume(void);
|
||||
|
||||
__PORT__ void port_systick_suspend(void);
|
||||
|
||||
__PORT__ void port_systick_reload(uint32_t cycle_per_tick);
|
||||
|
||||
__PORT__ void port_systick_pending_reset(void);
|
||||
|
||||
__PORT__ k_time_t port_systick_max_delay_millisecond(void);
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__PORT__ void port_sleep_mode_enter(void);
|
||||
|
||||
__PORT__ void port_stop_mode_enter(void);
|
||||
|
||||
__PORT__ void port_standby_mode_enter(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
__PORT__ void HardFault_Handler(void);
|
||||
|
||||
__PORT__ void port_fault_diagnosis(void);
|
||||
#endif
|
||||
|
||||
#endif /* _PORT_H_ */
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos_k.h"
|
||||
#include "core_cm0.h"
|
||||
|
||||
__PORT__ void port_cpu_reset(void)
|
||||
{
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_config(uint32_t cycle_per_tick)
|
||||
{
|
||||
(void)SysTick_Config(cycle_per_tick);
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_priority_set(uint32_t prio)
|
||||
{
|
||||
NVIC_SetPriority(SysTick_IRQn, prio);
|
||||
}
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN > 0u
|
||||
|
||||
__PORT__ k_time_t port_systick_max_delay_millisecond(void)
|
||||
{
|
||||
k_time_t max_millisecond;
|
||||
uint32_t max_cycle;
|
||||
|
||||
max_cycle = SysTick_LOAD_RELOAD_Msk; // 24 bit
|
||||
max_millisecond = (k_time_t)((uint64_t)max_cycle * K_TIME_MILLISEC_PER_SEC / TOS_CFG_CPU_CLOCK); // CLOCK: cycle per second
|
||||
return max_millisecond;
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_resume(void)
|
||||
{
|
||||
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
|
||||
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_suspend(void)
|
||||
{
|
||||
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
|
||||
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_reload(uint32_t cycle_per_tick)
|
||||
{
|
||||
port_systick_config(cycle_per_tick);
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_pending_reset(void)
|
||||
{
|
||||
SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__PORT__ void port_sleep_mode_enter(void)
|
||||
{
|
||||
#if 1
|
||||
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
|
||||
#else
|
||||
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
|
||||
#endif
|
||||
}
|
||||
|
||||
__PORT__ void port_stop_mode_enter(void)
|
||||
{
|
||||
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
|
||||
}
|
||||
|
||||
__PORT__ void port_standby_mode_enter(void)
|
||||
{
|
||||
HAL_PWR_EnterSTANDBYMode();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
__PORT__ void port_fault_diagnosis(void)
|
||||
{
|
||||
k_fault_log_writer("fault diagnosis is not supported in CORTEX M0\n");
|
||||
}
|
||||
|
||||
/*------------------ RealView Compiler -----------------*/
|
||||
/* V5 */
|
||||
#if defined(__CC_ARM)
|
||||
|
||||
__PORT__ __ASM__ void HardFault_Handler(void)
|
||||
{
|
||||
IMPORT fault_backtrace
|
||||
|
||||
MOV r0, lr
|
||||
MOVS r1, #0x04
|
||||
TST r0, r1
|
||||
BEQ _LD_MSP
|
||||
MRS r1, PSP
|
||||
B _EXIT
|
||||
|
||||
_LD_MSP
|
||||
MRS r1, MSP
|
||||
|
||||
_EXIT
|
||||
BL fault_backtrace
|
||||
}
|
||||
|
||||
/*------------------ ARM Compiler V6 -------------------*/
|
||||
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
|
||||
__PORT__ void __NAKED__ HardFault_Handler(void)
|
||||
{
|
||||
__ASM__ __VOLATILE__ (
|
||||
"MOV r0, lr\n\t"
|
||||
"MOVS r1, #0x04\n\t"
|
||||
"TST r0, r1\n\t"
|
||||
"BEQ _LD_MSP\n\t"
|
||||
"MRS r1, PSP\n\t"
|
||||
"B _EXIT\n\t"
|
||||
"_LD_MSP:\n\t"
|
||||
"MRS r1, MSP\n\t"
|
||||
"_EXIT:\n\t"
|
||||
"BL fault_backtrace\n\t"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* ARMCC VERSION */
|
||||
|
||||
#endif /* TOS_CFG_FAULT_BACKTRACE_EN */
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _PORT_CONFIG_H_
|
||||
#define _PORT_CONFIG_H_
|
||||
|
||||
#define TOS_CFG_CPU_ADDR_SIZE CPU_WORD_SIZE_32
|
||||
#define TOS_CFG_CPU_DATA_SIZE CPU_WORD_SIZE_32
|
||||
#define TOS_CFG_CPU_STK_GROWTH CPU_STK_GROWTH_DESCENDING
|
||||
// #define TOS_CFG_CPU_HRTIMER_SIZE CPU_WORD_SIZE_32
|
||||
#define TOS_CFG_CPU_HRTIMER_EN 0u
|
||||
#define TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT 0u
|
||||
#define TOS_CFG_CPU_BYTE_ORDER CPU_BYTE_ORDER_LITTLE_ENDIAN
|
||||
|
||||
#endif /* _PORT_CONFIG_H_ */
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
EXPORT port_int_disable
|
||||
EXPORT port_int_enable
|
||||
|
||||
EXPORT port_cpsr_save
|
||||
EXPORT port_cpsr_restore
|
||||
|
||||
EXPORT port_sched_start
|
||||
EXPORT port_context_switch
|
||||
EXPORT port_irq_context_switch
|
||||
|
||||
EXPORT PendSV_Handler
|
||||
|
||||
IMPORT k_curr_task
|
||||
IMPORT k_next_task
|
||||
|
||||
|
||||
NVIC_INT_CTRL EQU 0xE000ED04 ; Interrupt control state register.
|
||||
NVIC_SYSPRI14 EQU 0xE000ED20 ; System priority register (priority 14).
|
||||
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest).
|
||||
NVIC_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception.
|
||||
|
||||
|
||||
AREA |.text|, CODE, READONLY, ALIGN=2
|
||||
THUMB
|
||||
REQUIRE8
|
||||
PRESERVE8
|
||||
|
||||
GLOBAL port_int_disable
|
||||
port_int_disable
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
|
||||
GLOBAL port_int_enable
|
||||
port_int_enable
|
||||
CPSIE I
|
||||
BX LR
|
||||
|
||||
|
||||
GLOBAL port_cpsr_save
|
||||
port_cpsr_save
|
||||
MRS R0, PRIMASK
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
|
||||
GLOBAL port_cpsr_restore
|
||||
port_cpsr_restore
|
||||
MSR PRIMASK, R0
|
||||
BX LR
|
||||
|
||||
|
||||
GLOBAL port_sched_start
|
||||
port_sched_start
|
||||
LDR R0, =NVIC_SYSPRI14
|
||||
LDR R1, =NVIC_PENDSV_PRI
|
||||
STR R1, [R0]
|
||||
|
||||
MOVS R0, #0
|
||||
MSR PSP, R0
|
||||
|
||||
LDR R0, =NVIC_INT_CTRL
|
||||
LDR R1, =NVIC_PENDSVSET
|
||||
STR R1, [R0]
|
||||
|
||||
CPSIE I
|
||||
|
||||
__unreachable
|
||||
B __unreachable
|
||||
|
||||
|
||||
GLOBAL port_context_switch
|
||||
port_context_switch
|
||||
LDR R0, =NVIC_INT_CTRL
|
||||
LDR R1, =NVIC_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
|
||||
GLOBAL port_irq_context_switch
|
||||
port_irq_context_switch
|
||||
LDR R0, =NVIC_INT_CTRL
|
||||
LDR R1, =NVIC_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
|
||||
GLOBAL PendSV_Handler
|
||||
PendSV_Handler
|
||||
CPSID I
|
||||
MRS R0, PSP
|
||||
CMP R0, #0
|
||||
BEQ PendSVHandler_nosave
|
||||
|
||||
SUBS R0, R0, #0x20
|
||||
STMIA R0!, {R4 - R7}
|
||||
MOV R4, R8
|
||||
MOV R5, R9
|
||||
MOV R6, R10
|
||||
MOV R7, R11
|
||||
STMIA R0!, {R4-R7}
|
||||
SUBS R0, R0, #0x20
|
||||
|
||||
LDR R1, =k_curr_task
|
||||
LDR R1, [R1]
|
||||
STR R0, [R1]
|
||||
|
||||
PendSVHandler_nosave
|
||||
LDR R0, =k_curr_task
|
||||
LDR R1, =k_next_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
|
||||
LDR R0, [R2]
|
||||
|
||||
LDMIA R0!, {R4 - R7}
|
||||
LDMIA R0!, {R2 - R3}
|
||||
MOV R8, R2
|
||||
MOV R9, R3
|
||||
LDMIA R0!, {R2 - R3}
|
||||
MOV R10, R2
|
||||
MOV R11, R3
|
||||
MSR PSP, R0
|
||||
|
||||
MOV R0, R14
|
||||
MOVS R1, #0x04
|
||||
ORRS R0, R1
|
||||
MOV R14, R0
|
||||
|
||||
CPSIE I
|
||||
|
||||
BX LR
|
||||
|
||||
ALIGN
|
||||
|
||||
END
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _PORT_H_
|
||||
#define _PORT_H_
|
||||
|
||||
__PORT__ void port_int_disable(void);
|
||||
|
||||
__PORT__ void port_int_enable(void);
|
||||
|
||||
__PORT__ cpu_cpsr_t port_cpsr_save(void);
|
||||
|
||||
__PORT__ void port_cpsr_restore(cpu_cpsr_t cpsr);
|
||||
|
||||
__PORT__ void port_cpu_reset(void);
|
||||
|
||||
__PORT__ void port_sched_start(void) __NO_RETURN__;
|
||||
|
||||
__PORT__ void port_context_switch(void);
|
||||
|
||||
__PORT__ void port_irq_context_switch(void);
|
||||
|
||||
__PORT__ void port_systick_config(uint32_t cycle_per_tick);
|
||||
|
||||
__PORT__ void port_systick_priority_set(uint32_t prio);
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN > 0u
|
||||
|
||||
__PORT__ void port_systick_resume(void);
|
||||
|
||||
__PORT__ void port_systick_suspend(void);
|
||||
|
||||
__PORT__ void port_systick_reload(uint32_t cycle_per_tick);
|
||||
|
||||
__PORT__ void port_systick_pending_reset(void);
|
||||
|
||||
__PORT__ k_time_t port_systick_max_delay_millisecond(void);
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__PORT__ void port_sleep_mode_enter(void);
|
||||
|
||||
__PORT__ void port_stop_mode_enter(void);
|
||||
|
||||
__PORT__ void port_standby_mode_enter(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
__PORT__ void HardFault_Handler(void);
|
||||
|
||||
__PORT__ void port_fault_diagnosis(void);
|
||||
#endif
|
||||
|
||||
#endif /* _PORT_H_ */
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos_k.h"
|
||||
#include "core_cm0.h"
|
||||
|
||||
__PORT__ void port_cpu_reset(void)
|
||||
{
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_config(uint32_t cycle_per_tick)
|
||||
{
|
||||
(void)SysTick_Config(cycle_per_tick);
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_priority_set(uint32_t prio)
|
||||
{
|
||||
NVIC_SetPriority(SysTick_IRQn, prio);
|
||||
}
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN > 0u
|
||||
|
||||
__PORT__ k_time_t port_systick_max_delay_millisecond(void)
|
||||
{
|
||||
k_time_t max_millisecond;
|
||||
uint32_t max_cycle;
|
||||
|
||||
max_cycle = SysTick_LOAD_RELOAD_Msk; // 24 bit
|
||||
max_millisecond = (k_time_t)((uint64_t)max_cycle * K_TIME_MILLISEC_PER_SEC / TOS_CFG_CPU_CLOCK); // CLOCK: cycle per second
|
||||
return max_millisecond;
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_resume(void)
|
||||
{
|
||||
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
|
||||
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_suspend(void)
|
||||
{
|
||||
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
|
||||
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_reload(uint32_t cycle_per_tick)
|
||||
{
|
||||
port_systick_config(cycle_per_tick);
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_pending_reset(void)
|
||||
{
|
||||
SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__PORT__ void port_sleep_mode_enter(void)
|
||||
{
|
||||
#if 1
|
||||
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
|
||||
#else
|
||||
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
|
||||
#endif
|
||||
}
|
||||
|
||||
__PORT__ void port_stop_mode_enter(void)
|
||||
{
|
||||
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
|
||||
}
|
||||
|
||||
__PORT__ void port_standby_mode_enter(void)
|
||||
{
|
||||
HAL_PWR_EnterSTANDBYMode();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
__PORT__ void port_fault_diagnosis(void)
|
||||
{
|
||||
k_fault_log_writer("fault diagnosis is not supported in CORTEX M0\n");
|
||||
}
|
||||
|
||||
/*------------------ RealView Compiler -----------------*/
|
||||
/* V5 */
|
||||
#if defined(__CC_ARM)
|
||||
|
||||
__PORT__ __ASM__ void HardFault_Handler(void)
|
||||
{
|
||||
IMPORT fault_backtrace
|
||||
|
||||
MOV r0, lr
|
||||
TST lr, #0x04
|
||||
ITE EQ
|
||||
MRSEQ r1, MSP
|
||||
MRSNE r1, PSP
|
||||
BL fault_backtrace
|
||||
}
|
||||
|
||||
/*------------------ ARM Compiler V6 -------------------*/
|
||||
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
|
||||
__PORT__ void __NAKED__ HardFault_Handler(void)
|
||||
{
|
||||
__ASM__ __VOLATILE__ (
|
||||
"MOV r0, lr\n\t"
|
||||
"TST lr, #0x04\n\t"
|
||||
"ITE EQ\n\t"
|
||||
"MRSEQ r1, MSP\n\t"
|
||||
"MRSNE r1, PSP\n\t"
|
||||
"BL fault_backtrace\n\t"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* ARMCC VERSION */
|
||||
|
||||
#endif /* TOS_CFG_FAULT_BACKTRACE_EN */
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _PORT_CONFIG_H_
|
||||
#define _PORT_CONFIG_H_
|
||||
|
||||
#define TOS_CFG_CPU_ADDR_SIZE CPU_WORD_SIZE_32
|
||||
#define TOS_CFG_CPU_DATA_SIZE CPU_WORD_SIZE_32
|
||||
#define TOS_CFG_CPU_STK_GROWTH CPU_STK_GROWTH_DESCENDING
|
||||
// #define TOS_CFG_CPU_HRTIMER_SIZE CPU_WORD_SIZE_32
|
||||
#define TOS_CFG_CPU_HRTIMER_EN 0u
|
||||
#define TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT 0u
|
||||
#define TOS_CFG_CPU_BYTE_ORDER CPU_BYTE_ORDER_LITTLE_ENDIAN
|
||||
|
||||
#endif /* _PORT_CONFIG_H_ */
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
.global port_int_disable
|
||||
.global port_int_enable
|
||||
|
||||
.global port_cpsr_save
|
||||
.global port_cpsr_restore
|
||||
|
||||
.global port_sched_start
|
||||
.global port_context_switch
|
||||
.global port_irq_context_switch
|
||||
|
||||
.global PendSV_Handler
|
||||
|
||||
.global k_curr_task
|
||||
.global k_next_task
|
||||
|
||||
|
||||
.equ NVIC_INT_CTRL , 0xE000ED04 @Interrupt control state register.
|
||||
.equ NVIC_SYSPRI14 , 0xE000ED20 @System priority register (priority 14).
|
||||
.equ NVIC_PENDSV_PRI , 0x00FF0000 @ PendSV priority value (lowest).
|
||||
.equ NVIC_PENDSVSET , 0x10000000 @ Value to trigger PendSV exception.
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
.thumb
|
||||
.syntax unified
|
||||
|
||||
.type port_int_disable, %function
|
||||
port_int_disable:
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
|
||||
.type port_int_enable, %function
|
||||
port_int_enable:
|
||||
CPSIE I
|
||||
BX LR
|
||||
|
||||
|
||||
.type port_cpsr_save, %function
|
||||
port_cpsr_save:
|
||||
MRS R0, PRIMASK
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
|
||||
.type port_cpsr_restore, %function
|
||||
port_cpsr_restore:
|
||||
MSR PRIMASK, R0
|
||||
BX LR
|
||||
|
||||
|
||||
.thumb_func
|
||||
.type port_sched_start, %function
|
||||
port_sched_start:
|
||||
LDR R0, =NVIC_SYSPRI14
|
||||
|
||||
|
||||
LDR R1, =NVIC_PENDSV_PRI
|
||||
|
||||
|
||||
STR R1, [R0]
|
||||
|
||||
MOVS R0, #0
|
||||
MSR PSP, R0
|
||||
|
||||
LDR R0, =NVIC_INT_CTRL
|
||||
LDR R1, =NVIC_PENDSVSET
|
||||
STR R1, [R0]
|
||||
|
||||
CPSIE I
|
||||
|
||||
__unreachable:
|
||||
B __unreachable
|
||||
|
||||
|
||||
.thumb_func
|
||||
.type port_context_switch, %function
|
||||
port_context_switch:
|
||||
LDR R0, =NVIC_INT_CTRL
|
||||
LDR R1, =NVIC_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
|
||||
.thumb_func
|
||||
.type port_irq_context_switch, %function
|
||||
port_irq_context_switch:
|
||||
LDR R0, =NVIC_INT_CTRL
|
||||
LDR R1, =NVIC_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
|
||||
.thumb_func
|
||||
.type PendSV_Handler, %function
|
||||
PendSV_Handler:
|
||||
CPSID I
|
||||
MRS R0, PSP
|
||||
CMP R0, #0
|
||||
BEQ PendSVHandler_nosave
|
||||
|
||||
SUBS R0, R0, #0x20
|
||||
STMIA R0!, {R4 - R7}
|
||||
MOV R4, R8
|
||||
MOV R5, R9
|
||||
MOV R6, R10
|
||||
MOV R7, R11
|
||||
STMIA R0!, {R4-R7}
|
||||
SUBS R0, R0, #0x20
|
||||
|
||||
LDR R1, =k_curr_task
|
||||
LDR R1, [R1]
|
||||
STR R0, [R1]
|
||||
|
||||
PendSVHandler_nosave:
|
||||
LDR R0, =k_curr_task
|
||||
LDR R1, =k_next_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
|
||||
LDR R0, [R2]
|
||||
|
||||
LDMIA R0!, {R4 - R7}
|
||||
LDMIA R0!, {R2 - R3}
|
||||
MOV R8, R2
|
||||
MOV R9, R3
|
||||
LDMIA R0!, {R2 - R3}
|
||||
MOV R10, R2
|
||||
MOV R11, R3
|
||||
MSR PSP, R0
|
||||
|
||||
MOV R0, R14
|
||||
MOVS R1, #0x04
|
||||
ORRS R0, R1
|
||||
MOV R14, R0
|
||||
|
||||
CPSIE I
|
||||
|
||||
BX LR
|
||||
|
||||
.end
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _PORT_H_
|
||||
#define _PORT_H_
|
||||
|
||||
__PORT__ void port_int_disable(void);
|
||||
|
||||
__PORT__ void port_int_enable(void);
|
||||
|
||||
__PORT__ cpu_cpsr_t port_cpsr_save(void);
|
||||
|
||||
__PORT__ void port_cpsr_restore(cpu_cpsr_t cpsr);
|
||||
|
||||
__PORT__ void port_cpu_reset(void);
|
||||
|
||||
__PORT__ void port_sched_start(void) __NO_RETURN__;
|
||||
|
||||
__PORT__ void port_context_switch(void);
|
||||
|
||||
__PORT__ void port_irq_context_switch(void);
|
||||
|
||||
__PORT__ void port_systick_config(uint32_t cycle_per_tick);
|
||||
|
||||
__PORT__ void port_systick_priority_set(uint32_t prio);
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN > 0u
|
||||
|
||||
__PORT__ void port_systick_resume(void);
|
||||
|
||||
__PORT__ void port_systick_suspend(void);
|
||||
|
||||
__PORT__ void port_systick_reload(uint32_t cycle_per_tick);
|
||||
|
||||
__PORT__ void port_systick_pending_reset(void);
|
||||
|
||||
__PORT__ k_time_t port_systick_max_delay_millisecond(void);
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__PORT__ void port_sleep_mode_enter(void);
|
||||
|
||||
__PORT__ void port_stop_mode_enter(void);
|
||||
|
||||
__PORT__ void port_standby_mode_enter(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
__PORT__ void HardFault_Handler(void);
|
||||
|
||||
__PORT__ void port_fault_diagnosis(void);
|
||||
#endif
|
||||
|
||||
#endif /* _PORT_H_ */
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos_k.h"
|
||||
#include "core_cm0.h"
|
||||
|
||||
__PORT__ void port_cpu_reset(void)
|
||||
{
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_config(uint32_t cycle_per_tick)
|
||||
{
|
||||
(void)SysTick_Config(cycle_per_tick);
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_priority_set(uint32_t prio)
|
||||
{
|
||||
NVIC_SetPriority(SysTick_IRQn, prio);
|
||||
}
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN > 0u
|
||||
|
||||
__PORT__ k_time_t port_systick_max_delay_millisecond(void)
|
||||
{
|
||||
k_time_t max_millisecond;
|
||||
uint32_t max_cycle;
|
||||
|
||||
max_cycle = SysTick_LOAD_RELOAD_Msk; // 24 bit
|
||||
max_millisecond = (k_time_t)((uint64_t)max_cycle * K_TIME_MILLISEC_PER_SEC / TOS_CFG_CPU_CLOCK); // CLOCK: cycle per second
|
||||
return max_millisecond;
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_resume(void)
|
||||
{
|
||||
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
|
||||
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_suspend(void)
|
||||
{
|
||||
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
|
||||
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_reload(uint32_t cycle_per_tick)
|
||||
{
|
||||
port_systick_config(cycle_per_tick);
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_pending_reset(void)
|
||||
{
|
||||
SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__PORT__ void port_sleep_mode_enter(void)
|
||||
{
|
||||
#if 1
|
||||
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
|
||||
#else
|
||||
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
|
||||
#endif
|
||||
}
|
||||
|
||||
__PORT__ void port_stop_mode_enter(void)
|
||||
{
|
||||
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
|
||||
}
|
||||
|
||||
__PORT__ void port_standby_mode_enter(void)
|
||||
{
|
||||
HAL_PWR_EnterSTANDBYMode();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
|
||||
__PORT__ void port_fault_diagnosis(void)
|
||||
{
|
||||
k_fault_log_writer("fault diagnosis is not supported in CORTEX M0\n");
|
||||
}
|
||||
|
||||
__PORT__ void __NAKED__ HardFault_Handler(void)
|
||||
{
|
||||
__ASM__ __VOLATILE__ (
|
||||
"MOV r0, lr\n\t"
|
||||
"MOVS r1, #0x04\n\t"
|
||||
"TST r0, r1\n\t"
|
||||
"BEQ _LD_MSP\n\t"
|
||||
"MRS r1, PSP\n\t"
|
||||
"B _EXIT\n"
|
||||
"_LD_MSP:\n\t"
|
||||
"MRS r1, MSP\n"
|
||||
"_EXIT:\n\t"
|
||||
"LDR r2, =fault_backtrace\n\t"
|
||||
"BX r2\n\t"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* TOS_CFG_FAULT_BACKTRACE_EN */
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _PORT_CONFIG_H_
|
||||
#define _PORT_CONFIG_H_
|
||||
|
||||
#define TOS_CFG_CPU_ADDR_SIZE CPU_WORD_SIZE_32
|
||||
#define TOS_CFG_CPU_DATA_SIZE CPU_WORD_SIZE_32
|
||||
#define TOS_CFG_CPU_STK_GROWTH CPU_STK_GROWTH_DESCENDING
|
||||
// #define TOS_CFG_CPU_HRTIMER_SIZE CPU_WORD_SIZE_32
|
||||
#define TOS_CFG_CPU_HRTIMER_EN 0u
|
||||
#define TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT 0u
|
||||
#define TOS_CFG_CPU_BYTE_ORDER CPU_BYTE_ORDER_LITTLE_ENDIAN
|
||||
|
||||
#endif /* _PORT_CONFIG_H_ */
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
PUBLIC port_int_disable
|
||||
PUBLIC port_int_enable
|
||||
|
||||
PUBLIC port_cpsr_save
|
||||
PUBLIC port_cpsr_restore
|
||||
|
||||
PUBLIC port_sched_start
|
||||
PUBLIC port_context_switch
|
||||
PUBLIC port_irq_context_switch
|
||||
|
||||
PUBLIC PendSV_Handler
|
||||
|
||||
EXTERN k_curr_task
|
||||
EXTERN k_next_task
|
||||
|
||||
|
||||
NVIC_INT_CTRL EQU 0xE000ED04 ; Interrupt control state register.
|
||||
NVIC_SYSPRI14 EQU 0xE000ED20 ; System priority register (priority 14).
|
||||
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest).
|
||||
NVIC_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception.
|
||||
|
||||
|
||||
RSEG CODE:CODE:NOROOT(2)
|
||||
THUMB
|
||||
|
||||
port_int_disable
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
|
||||
port_int_enable
|
||||
CPSIE I
|
||||
BX LR
|
||||
|
||||
|
||||
port_cpsr_save
|
||||
MRS R0, PRIMASK
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
|
||||
port_cpsr_restore
|
||||
MSR PRIMASK, R0
|
||||
BX LR
|
||||
|
||||
|
||||
port_sched_start
|
||||
LDR R0, =NVIC_SYSPRI14
|
||||
LDR R1, =NVIC_PENDSV_PRI
|
||||
STR R1, [R0]
|
||||
|
||||
MOVS R0, #0
|
||||
MSR PSP, R0
|
||||
|
||||
LDR R0, =NVIC_INT_CTRL
|
||||
LDR R1, =NVIC_PENDSVSET
|
||||
STR R1, [R0]
|
||||
|
||||
CPSIE I
|
||||
|
||||
__unreachable
|
||||
B __unreachable
|
||||
|
||||
|
||||
port_context_switch
|
||||
LDR R0, =NVIC_INT_CTRL
|
||||
LDR R1, =NVIC_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
|
||||
port_irq_context_switch
|
||||
LDR R0, =NVIC_INT_CTRL
|
||||
LDR R1, =NVIC_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
|
||||
PendSV_Handler
|
||||
CPSID I
|
||||
MRS R0, PSP
|
||||
CMP R0, #0
|
||||
BEQ PendSVHandler_nosave
|
||||
|
||||
SUBS R0, R0, #0x20
|
||||
STMIA R0!, {R4 - R7}
|
||||
MOV R4, R8
|
||||
MOV R5, R9
|
||||
MOV R6, R10
|
||||
MOV R7, R11
|
||||
STMIA R0!, {R4-R7}
|
||||
SUBS R0, R0, #0x20
|
||||
|
||||
LDR R1, =k_curr_task
|
||||
LDR R1, [R1]
|
||||
STR R0, [R1]
|
||||
|
||||
PendSVHandler_nosave
|
||||
LDR R0, =k_curr_task
|
||||
LDR R1, =k_next_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
|
||||
LDR R0, [R2]
|
||||
|
||||
LDMIA R0!, {R4 - R7}
|
||||
LDMIA R0!, {R2 - R3}
|
||||
MOV R8, R2
|
||||
MOV R9, R3
|
||||
LDMIA R0!, {R2 - R3}
|
||||
MOV R10, R2
|
||||
MOV R11, R3
|
||||
MSR PSP, R0
|
||||
|
||||
MOV R0, R14
|
||||
MOVS R1, #0x04
|
||||
ORRS R0, R1
|
||||
MOV R14, R0
|
||||
|
||||
CPSIE I
|
||||
|
||||
BX LR
|
||||
|
||||
|
||||
END
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_ARM_H_
|
||||
#define _TOS_ARM_H_
|
||||
|
||||
#define DSB __ASM__ __VOLATILE__("dsb" ::: "memory")
|
||||
#define DMB __ASM__ __VOLATILE__("dmb" ::: "memory")
|
||||
#define ISB __ASM__ __VOLATILE__("isb" ::: "memory")
|
||||
|
||||
#define __STRINGIFY(x) #x
|
||||
|
||||
#define ARM_MCR(coproc, opcode_1, src, CRn, CRm, opcode_2) \
|
||||
__ASM__ __VOLATILE__ ("MCR " __STRINGIFY(p##coproc) ", " __STRINGIFY(opcode_1) ", " \
|
||||
"%0, " __STRINGIFY(c##CRn) ", " __STRINGIFY(c##CRm) ", " \
|
||||
__STRINGIFY(opcode_2) \
|
||||
: : "r" (src) )
|
||||
|
||||
#define ARM_MRC(coproc, opcode_1, CRn, CRm, opcode_2) \
|
||||
({ \
|
||||
uint32_t __dst; \
|
||||
__ASM__ __VOLATILE__ ("MRC " __STRINGIFY(p##coproc) ", " __STRINGIFY(opcode_1) ", " \
|
||||
"%0, " __STRINGIFY(c##CRn) ", " __STRINGIFY(c##CRm) ", " \
|
||||
__STRINGIFY(opcode_2) \
|
||||
: "=r" (__dst) ); \
|
||||
__dst; \
|
||||
})
|
||||
|
||||
#endif /* _TOS_ARM_H_ */
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_CHIP_H_
|
||||
#define _TOS_CHIP_H_
|
||||
|
||||
#include "chip/gic.h"
|
||||
#include "chip/chip.h"
|
||||
|
||||
void chip_init(void);
|
||||
|
||||
#endif /* _TOS_CHIP_H_ */
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_CPU_H_
|
||||
#define _TOS_CPU_H_
|
||||
|
||||
#include "tos_arm.h"
|
||||
#include "tos_chip.h"
|
||||
#include "tos_gic.h"
|
||||
#include "tos_interrupt.h"
|
||||
|
||||
typedef struct cpu_context_st {
|
||||
cpu_data_t r0;
|
||||
cpu_data_t r1;
|
||||
cpu_data_t r2;
|
||||
cpu_data_t r3;
|
||||
cpu_data_t r4;
|
||||
cpu_data_t r5;
|
||||
cpu_data_t r6;
|
||||
cpu_data_t r7;
|
||||
cpu_data_t r8;
|
||||
cpu_data_t r9;
|
||||
cpu_data_t r10;
|
||||
cpu_data_t r11;
|
||||
cpu_data_t r12;
|
||||
|
||||
cpu_data_t lr;
|
||||
|
||||
cpu_data_t pc;
|
||||
cpu_data_t cpsr;
|
||||
} cpu_context_t;
|
||||
|
||||
__API__ uint32_t tos_cpu_clz(uint32_t val);
|
||||
|
||||
__API__ void tos_cpu_int_disable(void);
|
||||
|
||||
__API__ void tos_cpu_int_enable(void);
|
||||
|
||||
__API__ cpu_cpsr_t tos_cpu_cpsr_save(void);
|
||||
|
||||
__API__ void tos_cpu_cpsr_restore(cpu_cpsr_t cpsr);
|
||||
|
||||
#if (TOS_CFG_CPU_HRTIMER_EN > 0u)
|
||||
|
||||
__API__ void tos_cpu_hrtimer_init(void);
|
||||
|
||||
__API__ cpu_hrtimer_t tos_cpu_hrtimer_read(void);
|
||||
|
||||
#endif
|
||||
|
||||
__KNL__ void cpu_init(void);
|
||||
|
||||
__KNL__ void cpu_reset(void);
|
||||
|
||||
__KNL__ void cpu_systick_init(k_cycle_t cycle_per_tick);
|
||||
|
||||
__KNL__ void cpu_sched_start(void);
|
||||
|
||||
__KNL__ void cpu_context_switch(void);
|
||||
|
||||
__KNL__ void cpu_irq_context_switch(void);
|
||||
|
||||
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
|
||||
|
||||
__KNL__ k_err_t cpu_task_stack_draught_depth(k_stack_t *stk_base, size_t stk_size, int *depth);
|
||||
|
||||
#endif
|
||||
|
||||
__KNL__ k_stack_t *cpu_task_stk_init(void *entry,
|
||||
void *arg,
|
||||
void *exit,
|
||||
k_stack_t *stk_base,
|
||||
size_t stk_size);
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN > 0u
|
||||
|
||||
__KNL__ void cpu_systick_resume(void);
|
||||
|
||||
__KNL__ void cpu_systick_suspend(void);
|
||||
|
||||
__KNL__ void cpu_systick_reload_reset(void);
|
||||
|
||||
__KNL__ void cpu_systick_pending_reset(void);
|
||||
|
||||
__KNL__ k_time_t cpu_systick_max_delay_millisecond(void);
|
||||
|
||||
__KNL__ void cpu_systick_expires_set(k_time_t millisecond);
|
||||
|
||||
__KNL__ void cpu_systick_reset(void);
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__KNL__ void cpu_sleep_mode_enter(void);
|
||||
|
||||
__KNL__ void cpu_stop_mode_enter(void);
|
||||
|
||||
__KNL__ void cpu_standby_mode_enter(void);
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
|
||||
__KNL__ void cpu_flush_fpu(void);
|
||||
|
||||
#endif /* TOS_CFG_CPU_ARM_FPU_EN */
|
||||
|
||||
__KNL__ void cpu_fault_diagnosis(void);
|
||||
|
||||
#endif
|
||||
|
||||
/* Allocates CPU status register word. */
|
||||
#define TOS_CPU_CPSR_ALLOC() cpu_cpsr_t cpu_cpsr = (cpu_cpsr_t)0u
|
||||
|
||||
/* Save CPU status word & disable interrupts.*/
|
||||
#define TOS_CPU_INT_DISABLE() \
|
||||
do { \
|
||||
cpu_cpsr = tos_cpu_cpsr_save(); \
|
||||
} while (0)
|
||||
|
||||
/* Restore CPU status word. */
|
||||
#define TOS_CPU_INT_ENABLE() \
|
||||
do { \
|
||||
tos_cpu_cpsr_restore(cpu_cpsr); \
|
||||
} while (0)
|
||||
|
||||
#endif /* _TOS_CPU_H_ */
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_CPU_DEF_H_
|
||||
#define _TOS_CPU_DEF_H_
|
||||
|
||||
#define CPU_WORD_SIZE_08 1
|
||||
#define CPU_WORD_SIZE_16 2
|
||||
#define CPU_WORD_SIZE_32 3
|
||||
#define CPU_WORD_SIZE_64 4
|
||||
|
||||
#define CPU_STK_GROWTH_ASCENDING 1
|
||||
#define CPU_STK_GROWTH_DESCENDING 2
|
||||
|
||||
#define CPU_BYTE_ORDER_LITTLE_ENDIAN 1
|
||||
#define CPU_BYTE_ORDER_BIG_ENDIAN 2
|
||||
|
||||
#endif /* _TOS_CPU_DEF_H_ */
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_CPU_TYPES_H_
|
||||
#define _TOS_CPU_TYPES_H_
|
||||
|
||||
/* CPU address type based on address bus size. */
|
||||
#if (TOS_CFG_CPU_ADDR_SIZE == CPU_WORD_SIZE_32)
|
||||
typedef uint32_t cpu_addr_t;
|
||||
#elif (TOS_CFG_CPU_ADDR_SIZE == CPU_WORD_SIZE_16)
|
||||
typedef uint16_t cpu_addr_t;
|
||||
#else
|
||||
typedef uint8_t cpu_addr_t;
|
||||
#endif
|
||||
|
||||
/* CPU data type based on data bus size. */
|
||||
#if (TOS_CFG_CPU_DATA_SIZE == CPU_WORD_SIZE_32)
|
||||
typedef uint32_t cpu_data_t;
|
||||
#elif (TOS_CFG_CPU_DATA_SIZE == CPU_WORD_SIZE_16)
|
||||
typedef uint16_t cpu_data_t;
|
||||
#else
|
||||
typedef uint8_t cpu_data_t;
|
||||
#endif
|
||||
|
||||
#if (TOS_CFG_CPU_HRTIMER_EN > 0)
|
||||
#if (TOS_CFG_CPU_HRTIMER_SIZE == CPU_WORD_SIZE_08)
|
||||
typedef uint8_t cpu_hrtimer_t;
|
||||
#elif (TOS_CFG_CPU_HRTIMER_SIZE == CPU_WORD_SIZE_16)
|
||||
typedef uint16_t cpu_hrtimer_t;
|
||||
#elif (TOS_CFG_CPU_HRTIMER_SIZE == CPU_WORD_SIZE_64)
|
||||
typedef uint64_t cpu_hrtimer_t;
|
||||
#else
|
||||
typedef uint32_t cpu_hrtimer_t;
|
||||
#endif
|
||||
#else
|
||||
typedef uint32_t cpu_hrtimer_t;
|
||||
#endif
|
||||
|
||||
typedef cpu_addr_t cpu_cpsr_t;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_FAULT_H_
|
||||
#define _TOS_FAULT_H_
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
|
||||
typedef int (*k_fault_log_writer_t)(const char *format, ...);
|
||||
|
||||
#define K_FAULT_STACK_DUMP_DEPTH 10u
|
||||
|
||||
#define K_FAULT_CALL_STACK_BACKTRACE_DEPTH 5u
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
typedef struct fault_fpu_frame_st {
|
||||
cpu_data_t s0;
|
||||
cpu_data_t s1;
|
||||
cpu_data_t s2;
|
||||
cpu_data_t s3;
|
||||
cpu_data_t s4;
|
||||
cpu_data_t s5;
|
||||
cpu_data_t s6;
|
||||
cpu_data_t s7;
|
||||
cpu_data_t s8;
|
||||
cpu_data_t s9;
|
||||
cpu_data_t s10;
|
||||
cpu_data_t s11;
|
||||
cpu_data_t s12;
|
||||
cpu_data_t s13;
|
||||
cpu_data_t s14;
|
||||
cpu_data_t s15;
|
||||
cpu_data_t fpscr;
|
||||
} fault_fpu_frame_t;
|
||||
#endif
|
||||
|
||||
typedef struct fault_cpu_frame_st {
|
||||
cpu_data_t r0;
|
||||
cpu_data_t r1;
|
||||
cpu_data_t r2;
|
||||
cpu_data_t r3;
|
||||
cpu_data_t r12;
|
||||
cpu_data_t lr;
|
||||
cpu_data_t pc;
|
||||
cpu_data_t spsr;
|
||||
} fault_cpu_frame_t;
|
||||
|
||||
typedef struct fault_exc_frame_st {
|
||||
fault_cpu_frame_t cpu_frame;
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
fault_fpu_frame_t fpu_frame;
|
||||
#endif
|
||||
} fault_exc_frame_t;
|
||||
|
||||
/**
|
||||
* information we need to do fault backtrace
|
||||
*/
|
||||
typedef struct fault_information_st {
|
||||
int is_thumb : 1; /**< whether it is thumb we use when we fall into fault? */
|
||||
int is_on_task : 1; /**< whether we are on a task when fall into fault? */
|
||||
int is_stk_ovrf : 1; /**< whether we get a stack overflow */
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
int is_ext_stk_frm : 1; /**< whether it is a extended stack frame?(whether the cpu has pushed fpu registers onto the stack) */
|
||||
#endif
|
||||
|
||||
cpu_addr_t pc; /**< just where fault happens */
|
||||
|
||||
cpu_addr_t sp_before_fault; /**< original sp just before the cpu push the fault exception frame */
|
||||
|
||||
/**
|
||||
* we need main_stack_start & main_stack_limit to do call stack backtrace
|
||||
* when we fall into fault during a task, we should do the call stack backtrace on the task's stack
|
||||
* but if not, which means we are in kernel, we should do the call stack backtrace on the main stack
|
||||
* in arm v7-m, this should be the MSP's start and limit
|
||||
* in arm v7-a, call stack backtrace is another story(much more elegant because we have FP).
|
||||
*/
|
||||
cpu_addr_t stack_start; /**< current sp start address we use. if on task, it'll be the task's stack, otherwise it'll be the msp */
|
||||
cpu_addr_t stack_limit; /**< current sp limit address */
|
||||
cpu_addr_t code_start; /**< current code start address */
|
||||
cpu_addr_t code_limit; /**< current code limit address */
|
||||
} fault_info_t;
|
||||
|
||||
#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
|
||||
|
||||
#define DEFAULT_CODE_SECTION_NAME ER_IROM1
|
||||
#define DEFAULT_CSTACK_SECTION_NAME STACK
|
||||
|
||||
#define SECTION_START(_name_) _name_##$$Base
|
||||
#define SECTION_END(_name_) _name_##$$Limit
|
||||
#define IMAGE_SECTION_START(_name_) Image$$##_name_##$$Base
|
||||
#define IMAGE_SECTION_END(_name_) Image$$##_name_##$$Limit
|
||||
#define CSTACK_BLOCK_START(_name_) SECTION_START(_name_)
|
||||
#define CSTACK_BLOCK_END(_name_) SECTION_END(_name_)
|
||||
#define CODE_SECTION_START(_name_) IMAGE_SECTION_START(_name_)
|
||||
#define CODE_SECTION_END(_name_) IMAGE_SECTION_END(_name_)
|
||||
|
||||
extern const int CSTACK_BLOCK_START(DEFAULT_CSTACK_SECTION_NAME);
|
||||
extern const int CSTACK_BLOCK_END(DEFAULT_CSTACK_SECTION_NAME);
|
||||
extern const int CODE_SECTION_START(DEFAULT_CODE_SECTION_NAME);
|
||||
extern const int CODE_SECTION_END(DEFAULT_CODE_SECTION_NAME);
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_code_start(void)
|
||||
{
|
||||
return (cpu_addr_t)&CODE_SECTION_START(DEFAULT_CODE_SECTION_NAME);
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_code_limit(void)
|
||||
{
|
||||
return (cpu_addr_t)&CODE_SECTION_END(DEFAULT_CODE_SECTION_NAME);
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_msp_start(void)
|
||||
{
|
||||
return (cpu_addr_t)&CSTACK_BLOCK_START(DEFAULT_CSTACK_SECTION_NAME);
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_msp_limit(void)
|
||||
{
|
||||
return (cpu_addr_t)&CSTACK_BLOCK_END(DEFAULT_CSTACK_SECTION_NAME);
|
||||
}
|
||||
|
||||
#elif defined(__ICCARM__)
|
||||
|
||||
#define DEFAULT_CODE_SECTION_NAME ".text"
|
||||
#define DEFAULT_CSTACK_SECTION_NAME "CSTACK"
|
||||
|
||||
#pragma section=DEFAULT_CSTACK_SECTION_NAME
|
||||
#pragma section=DEFAULT_CODE_SECTION_NAME
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_code_start(void)
|
||||
{
|
||||
return (cpu_addr_t)__section_begin(DEFAULT_CODE_SECTION_NAME);
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_code_limit(void)
|
||||
{
|
||||
return (cpu_addr_t)__section_end(DEFAULT_CODE_SECTION_NAME);
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_msp_start(void)
|
||||
{
|
||||
return (cpu_addr_t)__section_begin(DEFAULT_CSTACK_SECTION_NAME);
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_msp_limit(void)
|
||||
{
|
||||
return (cpu_addr_t)__section_end(DEFAULT_CSTACK_SECTION_NAME);
|
||||
}
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
/**
|
||||
* if we are using keil(armcc) or mdk(iccarm), we probably use the defult link script supplied by the IDE.
|
||||
* the way to locate the text/stack section start and limit is to find them in default link script.
|
||||
* but if we build our project by makefile(or something like scons, cmake, etc), we probably need to write
|
||||
* our own link scrpit, if so, we should do like this(just a demo):
|
||||
*
|
||||
_stext = .;
|
||||
.text : {
|
||||
*(.text.startup)
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
}
|
||||
_etext = .;
|
||||
|
||||
__bss_start = .;
|
||||
.bss : {
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(COMMON)
|
||||
_sstack = .;
|
||||
*(.cstack)
|
||||
_estack = .;
|
||||
}
|
||||
__bss_end = .;
|
||||
* by this, we can locate text/stack section start and limit by _stext/_etext and _sstack/_estack
|
||||
*/
|
||||
#define DEFAULT_CODE_SECTION_START _stext
|
||||
#define DEFAULT_CODE_SECTION_END _etext
|
||||
#define DEFAULT_CSTACK_SECTION_START _sstack
|
||||
#define DEFAULT_CSTACK_SECTION_END _estack
|
||||
|
||||
extern const int DEFAULT_CODE_SECTION_START;
|
||||
extern const int DEFAULT_CODE_SECTION_END;
|
||||
|
||||
extern const int DEFAULT_CSTACK_SECTION_START;
|
||||
extern const int DEFAULT_CSTACK_SECTION_END;
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_code_start(void)
|
||||
{
|
||||
return (cpu_addr_t)(&(DEFAULT_CODE_SECTION_START));
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_code_limit(void)
|
||||
{
|
||||
return (cpu_addr_t)(&(DEFAULT_CODE_SECTION_END));
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_msp_start(void)
|
||||
{
|
||||
return (cpu_addr_t)(&(DEFAULT_CSTACK_SECTION_START));
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_msp_limit(void)
|
||||
{
|
||||
return (cpu_addr_t)(&(DEFAULT_CSTACK_SECTION_END));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
__API__ void tos_fault_log_writer_set(k_fault_log_writer_t log_writer);
|
||||
|
||||
__KNL__ int fault_default_log_writer(const char *format, ...);
|
||||
|
||||
__KNL__ void fault_backtrace(cpu_addr_t lr, fault_exc_frame_t *frame);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _TOS_FAULT_H_ */
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_GIC_H_
|
||||
#define _TOS_GIC_H_
|
||||
|
||||
typedef struct gic_distributor_registers_st {
|
||||
uint32_t D_CTLR; /*!< Offset: 0x1000 (R/W) Distributor Control Register */
|
||||
uint32_t D_TYPER; /*!< Offset: 0x1004 (R/ ) Interrupt Controller Type Register */
|
||||
uint32_t D_IIDR; /*!< Offset: 0x1008 (R/ ) Distributor Implementer Identification Register */
|
||||
uint32_t RESERVED1[29];
|
||||
uint32_t D_IGROUPR[16]; /*!< Offset: 0x1080 - 0x0BC (R/W) Interrupt Group Registers */
|
||||
uint32_t RESERVED2[16];
|
||||
uint32_t D_ISENABLER[16]; /*!< Offset: 0x1100 - 0x13C (R/W) Interrupt Set-Enable Registers */
|
||||
uint32_t RESERVED3[16];
|
||||
uint32_t D_ICENABLER[16]; /*!< Offset: 0x1180 - 0x1BC (R/W) Interrupt Clear-Enable Registers */
|
||||
uint32_t RESERVED4[16];
|
||||
uint32_t D_ISPENDR[16]; /*!< Offset: 0x1200 - 0x23C (R/W) Interrupt Set-Pending Registers */
|
||||
uint32_t RESERVED5[16];
|
||||
uint32_t D_ICPENDR[16]; /*!< Offset: 0x1280 - 0x2BC (R/W) Interrupt Clear-Pending Registers */
|
||||
uint32_t RESERVED6[16];
|
||||
uint32_t D_ISACTIVER[16]; /*!< Offset: 0x1300 - 0x33C (R/W) Interrupt Set-Active Registers */
|
||||
uint32_t RESERVED7[16];
|
||||
uint32_t D_ICACTIVER[16]; /*!< Offset: 0x1380 - 0x3BC (R/W) Interrupt Clear-Active Registers */
|
||||
uint32_t RESERVED8[16];
|
||||
uint8_t D_IPRIORITYR[512]; /*!< Offset: 0x1400 - 0x5FC (R/W) Interrupt Priority Registers */
|
||||
uint32_t RESERVED9[128];
|
||||
uint8_t D_ITARGETSR[512]; /*!< Offset: 0x1800 - 0x9FC (R/W) Interrupt Targets Registers */
|
||||
uint32_t RESERVED10[128];
|
||||
uint32_t D_ICFGR[32]; /*!< Offset: 0x1C00 - 0xC7C (R/W) Interrupt configuration registers */
|
||||
uint32_t RESERVED11[32];
|
||||
uint32_t D_PPISR; /*!< Offset: 0x1D00 (R/ ) Private Peripheral Interrupt Status Register */
|
||||
uint32_t D_SPISR[15]; /*!< Offset: 0x1D04 - 0xD3C (R/ ) Shared Peripheral Interrupt Status Registers */
|
||||
uint32_t RESERVED12[112];
|
||||
uint32_t D_SGIR; /*!< Offset: 0x1F00 ( /W) Software Generated Interrupt Register */
|
||||
uint32_t RESERVED13[3];
|
||||
uint8_t D_CPENDSGIR[16]; /*!< Offset: 0x1F10 - 0xF1C (R/W) SGI Clear-Pending Registers */
|
||||
uint8_t D_SPENDSGIR[16]; /*!< Offset: 0x1F20 - 0xF2C (R/W) SGI Set-Pending Registers */
|
||||
uint32_t RESERVED14[40];
|
||||
uint32_t D_PIDR4; /*!< Offset: 0x1FD0 (R/ ) Peripheral ID4 Register */
|
||||
uint32_t D_PIDR5; /*!< Offset: 0x1FD4 (R/ ) Peripheral ID5 Register */
|
||||
uint32_t D_PIDR6; /*!< Offset: 0x1FD8 (R/ ) Peripheral ID6 Register */
|
||||
uint32_t D_PIDR7; /*!< Offset: 0x1FDC (R/ ) Peripheral ID7 Register */
|
||||
uint32_t D_PIDR0; /*!< Offset: 0x1FE0 (R/ ) Peripheral ID0 Register */
|
||||
uint32_t D_PIDR1; /*!< Offset: 0x1FE4 (R/ ) Peripheral ID1 Register */
|
||||
uint32_t D_PIDR2; /*!< Offset: 0x1FE8 (R/ ) Peripheral ID2 Register */
|
||||
uint32_t D_PIDR3; /*!< Offset: 0x1FEC (R/ ) Peripheral ID3 Register */
|
||||
uint32_t D_CIDR0; /*!< Offset: 0x1FF0 (R/ ) Component ID0 Register */
|
||||
uint32_t D_CIDR1; /*!< Offset: 0x1FF4 (R/ ) Component ID1 Register */
|
||||
uint32_t D_CIDR2; /*!< Offset: 0x1FF8 (R/ ) Component ID2 Register */
|
||||
uint32_t D_CIDR3; /*!< Offset: 0x1FFC (R/ ) Component ID3 Register */
|
||||
} gic_dist_t;
|
||||
|
||||
typedef struct gic_cpu_interface_registers_st {
|
||||
uint32_t C_CTLR; /*!< Offset: 0x2000 (R/W) CPU Interface Control Register */
|
||||
uint32_t C_PMR; /*!< Offset: 0x2004 (R/W) Interrupt Priority Mask Register */
|
||||
uint32_t C_BPR; /*!< Offset: 0x2008 (R/W) Binary Point Register */
|
||||
uint32_t C_IAR; /*!< Offset: 0x200C (R/ ) Interrupt Acknowledge Register */
|
||||
uint32_t C_EOIR; /*!< Offset: 0x2010 ( /W) End Of Interrupt Register */
|
||||
uint32_t C_RPR; /*!< Offset: 0x2014 (R/ ) Running Priority Register */
|
||||
uint32_t C_HPPIR; /*!< Offset: 0x2018 (R/ ) Highest Priority Pending Interrupt Register */
|
||||
uint32_t C_ABPR; /*!< Offset: 0x201C (R/W) Aliased Binary Point Register */
|
||||
uint32_t C_AIAR; /*!< Offset: 0x2020 (R/ ) Aliased Interrupt Acknowledge Register */
|
||||
uint32_t C_AEOIR; /*!< Offset: 0x2024 ( /W) Aliased End Of Interrupt Register */
|
||||
uint32_t C_AHPPIR; /*!< Offset: 0x2028 (R/ ) Aliased Highest Priority Pending Interrupt Register */
|
||||
uint32_t RESERVED15[41];
|
||||
uint32_t C_APR0; /*!< Offset: 0x20D0 (R/W) Active Priority Register */
|
||||
uint32_t RESERVED16[3];
|
||||
uint32_t C_NSAPR0; /*!< Offset: 0x20E0 (R/W) Non-secure Active Priority Register */
|
||||
uint32_t RESERVED17[6];
|
||||
uint32_t C_IIDR; /*!< Offset: 0x20FC (R/ ) CPU Interface Identification Register */
|
||||
uint32_t RESERVED18[960];
|
||||
uint32_t C_DIR; /*!< Offset: 0x3000 ( /W) Deactivate Interrupt Register */
|
||||
} gic_cpu_t;
|
||||
|
||||
typedef struct gic_data_st {
|
||||
gic_dist_t *dist;
|
||||
gic_cpu_t *cpu;
|
||||
} gic_data_t;
|
||||
|
||||
__KNL__ uint32_t gic_interrupt_id_get(uint32_t gic_nr);
|
||||
|
||||
__KNL__ void gic_interrupt_end(uint32_t gic_nr, uint32_t vector);
|
||||
|
||||
__KNL__ int gic_init(uint32_t gic_nr);
|
||||
|
||||
__KNL__ void gic_interrupt_enable(uint32_t gic_nr, uint32_t vector);
|
||||
|
||||
__KNL__ void gic_interrupt_disable(uint32_t gic_nr, uint32_t vector);
|
||||
|
||||
#endif /* _TOS_GIC_H_ */
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_INTERRUPT_H_
|
||||
#define _TOS_INTERRUPT_H_
|
||||
|
||||
typedef void (*int_handler_t)(void *arg);
|
||||
|
||||
typedef struct int_handle_st {
|
||||
int_handler_t handler;
|
||||
void *arg;
|
||||
} int_handle_t;
|
||||
|
||||
typedef struct int_frame_st {
|
||||
#if 0
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
uint32_t fpexc;
|
||||
#endif
|
||||
#endif
|
||||
cpu_data_t r0;
|
||||
cpu_data_t r1;
|
||||
cpu_data_t r2;
|
||||
cpu_data_t r3;
|
||||
cpu_data_t r4;
|
||||
cpu_data_t r5;
|
||||
cpu_data_t r6;
|
||||
cpu_data_t r7;
|
||||
cpu_data_t r8;
|
||||
cpu_data_t r9;
|
||||
cpu_data_t r10;
|
||||
cpu_data_t r11;
|
||||
cpu_data_t r12;
|
||||
|
||||
cpu_data_t lr;
|
||||
|
||||
cpu_data_t pc;
|
||||
cpu_data_t spsr;
|
||||
} int_frame_t;
|
||||
|
||||
__KNL__ void interrupt_irq(int_frame_t *int_frame);
|
||||
|
||||
__KNL__ int interrupt_init(void);
|
||||
|
||||
__API__ int tos_interrupt_handler_register(uint32_t vector, int_handler_t handler, void *arg);
|
||||
|
||||
__API__ void tos_interrupt_enable(uint32_t vector);
|
||||
|
||||
__API__ void tos_interrupt_disable(uint32_t vector);
|
||||
|
||||
#endif /* _TOS_INTERRUPT_H_ */
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos_k.h"
|
||||
|
||||
#define __STUB__ __WEAK__
|
||||
|
||||
__STUB__ void chip_init(void)
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,286 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos_k.h"
|
||||
|
||||
__API__ uint32_t tos_cpu_clz(uint32_t val)
|
||||
{
|
||||
#if defined(TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT) && (TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT == 0u)
|
||||
uint32_t nbr_lead_zeros = 0;
|
||||
|
||||
if (!(val & 0XFFFF0000)) {
|
||||
val <<= 16;
|
||||
nbr_lead_zeros += 16;
|
||||
}
|
||||
|
||||
if (!(val & 0XFF000000)) {
|
||||
val <<= 8;
|
||||
nbr_lead_zeros += 8;
|
||||
}
|
||||
|
||||
if (!(val & 0XF0000000)) {
|
||||
val <<= 4;
|
||||
nbr_lead_zeros += 4;
|
||||
}
|
||||
|
||||
if (!(val & 0XC0000000)) {
|
||||
val <<= 2;
|
||||
nbr_lead_zeros += 2;
|
||||
}
|
||||
|
||||
if (!(val & 0X80000000)) {
|
||||
nbr_lead_zeros += 1;
|
||||
}
|
||||
|
||||
if (!val) {
|
||||
nbr_lead_zeros += 1;
|
||||
}
|
||||
|
||||
return (nbr_lead_zeros);
|
||||
#else
|
||||
return port_clz(val);
|
||||
#endif
|
||||
}
|
||||
|
||||
__API__ void tos_cpu_int_disable(void)
|
||||
{
|
||||
port_int_disable();
|
||||
}
|
||||
|
||||
__API__ void tos_cpu_int_enable(void)
|
||||
{
|
||||
port_int_enable();
|
||||
}
|
||||
|
||||
__API__ cpu_cpsr_t tos_cpu_cpsr_save(void)
|
||||
{
|
||||
return port_cpsr_save();
|
||||
}
|
||||
|
||||
__API__ void tos_cpu_cpsr_restore(cpu_cpsr_t cpsr)
|
||||
{
|
||||
port_cpsr_restore(cpsr);
|
||||
}
|
||||
|
||||
__KNL__ void cpu_init(void)
|
||||
{
|
||||
k_cpu_cycle_per_tick = TOS_CFG_CPU_CLOCK / k_cpu_tick_per_second;
|
||||
|
||||
interrupt_init();
|
||||
chip_init();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_reset(void)
|
||||
{
|
||||
port_cpu_reset();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_sched_start(void)
|
||||
{
|
||||
port_sched_start();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_context_switch(void)
|
||||
{
|
||||
port_context_switch();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_irq_context_switch(void)
|
||||
{
|
||||
port_irq_context_switch();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_systick_init(k_cycle_t cycle_per_tick)
|
||||
{
|
||||
port_systick_priority_set(TOS_CFG_CPU_SYSTICK_PRIO);
|
||||
port_systick_config(cycle_per_tick);
|
||||
}
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN > 0u
|
||||
|
||||
/**
|
||||
* @brief Set value to systick reload value register
|
||||
*
|
||||
* @param cycles The value set to register
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__STATIC_INLINE__ void cpu_systick_reload(k_cycle_t cycle_per_tick)
|
||||
{
|
||||
port_systick_reload(cycle_per_tick);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable systick interrupt
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__KNL__ void cpu_systick_resume(void)
|
||||
{
|
||||
port_systick_resume();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable systick interrupt
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__KNL__ void cpu_systick_suspend(void)
|
||||
{
|
||||
port_systick_suspend();
|
||||
}
|
||||
|
||||
__KNL__ k_time_t cpu_systick_max_delay_millisecond(void)
|
||||
{
|
||||
return port_systick_max_delay_millisecond();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_systick_expires_set(k_time_t millisecond)
|
||||
{
|
||||
k_cycle_t cycles;
|
||||
|
||||
cycles = (k_cycle_t)((uint64_t)millisecond * TOS_CFG_CPU_CLOCK / K_TIME_MILLISEC_PER_SEC); /* CLOCK means cycle per second */
|
||||
|
||||
cpu_systick_reload(cycles - 12); /* interrupt delay */
|
||||
}
|
||||
|
||||
__KNL__ void cpu_systick_pending_reset(void)
|
||||
{
|
||||
port_systick_pending_reset();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_systick_reset(void)
|
||||
{
|
||||
cpu_systick_reload(k_cpu_cycle_per_tick);
|
||||
}
|
||||
|
||||
#endif /* TOS_CFG_TICKLESS_EN */
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__KNL__ void cpu_sleep_mode_enter(void)
|
||||
{
|
||||
port_sleep_mode_enter();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_stop_mode_enter(void)
|
||||
{
|
||||
port_stop_mode_enter();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_standby_mode_enter(void)
|
||||
{
|
||||
port_standby_mode_enter();
|
||||
}
|
||||
|
||||
#endif /* TOS_CFG_PWR_MGR_EN */
|
||||
|
||||
__KNL__ k_stack_t *cpu_task_stk_init(void *entry,
|
||||
void *arg,
|
||||
void *exit,
|
||||
k_stack_t *stk_base,
|
||||
size_t stk_size)
|
||||
{
|
||||
cpu_data_t *sp;
|
||||
cpu_context_t *context;
|
||||
|
||||
sp = (cpu_data_t *)&stk_base[stk_size];
|
||||
sp = (cpu_data_t *)((cpu_addr_t)sp & 0xFFFFFFF8);
|
||||
|
||||
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
|
||||
uint8_t *slot = (uint8_t *)&stk_base[0];
|
||||
for (; slot < (uint8_t *)sp; ++slot) {
|
||||
*slot = 0xCC;
|
||||
}
|
||||
#endif
|
||||
|
||||
context = (cpu_context_t *)sp;
|
||||
--context;
|
||||
|
||||
#define CPSR_SVC_MODE 0x13
|
||||
#define CPSR_BIT_T 0x20
|
||||
/* we donnot set the irq bit, so first time context switch should enable irq */
|
||||
context->cpsr = CPSR_SVC_MODE;
|
||||
if ((cpu_addr_t)entry & 1) {
|
||||
context->cpsr |= CPSR_BIT_T;
|
||||
}
|
||||
|
||||
context->pc = (cpu_data_t)entry;
|
||||
context->lr = (cpu_data_t)exit;
|
||||
|
||||
context->r12 = (cpu_data_t)0x12121212u;
|
||||
context->r11 = (cpu_data_t)0x11111111u;
|
||||
context->r10 = (cpu_data_t)0x10101010u;
|
||||
context->r9 = (cpu_data_t)0x09090909u;
|
||||
context->r8 = (cpu_data_t)0x08080808u;
|
||||
context->r7 = (cpu_data_t)0x07070707u;
|
||||
context->r6 = (cpu_data_t)0x06060606u;
|
||||
context->r5 = (cpu_data_t)0x05050505u;
|
||||
context->r4 = (cpu_data_t)0x04040404u;
|
||||
context->r3 = (cpu_data_t)0x03030303u;
|
||||
context->r2 = (cpu_data_t)0x02020202u;
|
||||
context->r1 = (cpu_data_t)0x01010101u;
|
||||
context->r0 = (cpu_data_t)arg;
|
||||
|
||||
return (k_stack_t *)context;
|
||||
}
|
||||
|
||||
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
|
||||
|
||||
__KNL__ k_err_t cpu_task_stack_draught_depth(k_stack_t *stk_base, size_t stk_size, int *depth)
|
||||
{
|
||||
uint8_t *slot;
|
||||
uint8_t *sp, *bp;
|
||||
int the_depth = 0;
|
||||
|
||||
bp = (uint8_t *)&stk_base[0];
|
||||
|
||||
sp = &stk_base[stk_size];
|
||||
sp = (uint8_t *)((cpu_addr_t)sp & 0xFFFFFFF8);
|
||||
|
||||
for (slot = sp - 1; slot >= bp; --slot) {
|
||||
if (*slot != 0xCC) {
|
||||
the_depth = sp - slot;
|
||||
}
|
||||
}
|
||||
|
||||
*depth = the_depth;
|
||||
if (the_depth == stk_size) {
|
||||
return K_ERR_TASK_STK_OVERFLOW;
|
||||
}
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
__KNL__ void cpu_flush_fpu(void)
|
||||
{
|
||||
(void)__get_FPSCR();
|
||||
}
|
||||
#endif
|
||||
|
||||
__KNL__ void cpu_fault_diagnosis(void)
|
||||
{
|
||||
port_fault_diagnosis();
|
||||
}
|
||||
|
||||
#endif /* TOS_CFG_FAULT_BACKTRACE_EN */
|
||||
|
|
@ -0,0 +1,392 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos_k.h"
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
|
||||
__STATIC_INLINE__ void fault_spin(void)
|
||||
{
|
||||
tos_knl_sched_lock();
|
||||
tos_cpu_int_disable();
|
||||
while (K_TRUE) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/* EXC_RETURN:
|
||||
31 - 28 : EXC_RETURN flag
|
||||
27 - 5 : reserved
|
||||
4 : 1, basic stack frame; 0, extended stack frame
|
||||
3 : 1, return to Thread mode; 0, return to Handler mode
|
||||
2 : 1, return to PSP; 0, return to MSP
|
||||
1 : reserved, 0
|
||||
0 : reserved, 1
|
||||
*/
|
||||
__STATIC_INLINE__ int fault_is_on_task(cpu_data_t lr)
|
||||
{
|
||||
return (lr & (1u << 2)) != 0;
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ int fault_is_thumb(cpu_data_t psr)
|
||||
{
|
||||
return (psr & (1u << 24)) != 0;
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ int fault_is_code(fault_info_t *info, cpu_data_t value)
|
||||
{
|
||||
return value >= info->code_start && value <= info->code_limit;
|
||||
}
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
__STATIC_INLINE__ int fault_is_extended_stack_frame(cpu_data_t lr)
|
||||
{
|
||||
return (lr & (1u << 4)) == 0;
|
||||
}
|
||||
|
||||
__STATIC__ void fault_dump_fpu_frame(fault_fpu_frame_t *fpu_frame)
|
||||
{
|
||||
/*
|
||||
* As known, v7-m has a feature named "LAZY PUSH", for the reason we do not do any float
|
||||
* operation in fault_backtrace, cpu will not do the real fpu register push to the stack.
|
||||
* that means the value we dump in fault_dump_fpu_frame will not be the correct value of
|
||||
* each FPU register.
|
||||
* We define a function here which access to FPSCR, if this function involved, cpu will do
|
||||
* the real FPU register push so we will get the correct dump.
|
||||
* I know it's ugly, but it works. If you know a better way, please tell me.
|
||||
*/
|
||||
cpu_flush_fpu();
|
||||
|
||||
k_fault_log_writer("\n\n====================== FPU Registers =======================\n");
|
||||
k_fault_log_writer(" %s: %08x\n", "FPSCR", fpu_frame->fpscr);
|
||||
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||
"S0 ", fpu_frame->s0,
|
||||
"S1 ", fpu_frame->s1,
|
||||
"S2 ", fpu_frame->s2,
|
||||
"S3 ", fpu_frame->s3);
|
||||
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||
"S4 ", fpu_frame->s4,
|
||||
"S5 ", fpu_frame->s5,
|
||||
"S6 ", fpu_frame->s6,
|
||||
"S7 ", fpu_frame->s7);
|
||||
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||
"S8 ", fpu_frame->s8,
|
||||
"S9 ", fpu_frame->s9,
|
||||
"S10", fpu_frame->s10,
|
||||
"S11", fpu_frame->s11);
|
||||
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||
"S12", fpu_frame->s12,
|
||||
"S13", fpu_frame->s13,
|
||||
"S14", fpu_frame->s14,
|
||||
"S15", fpu_frame->s15);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
__STATIC__ void fault_dump_cpu_frame(fault_cpu_frame_t *cpu_frame)
|
||||
{
|
||||
k_fault_log_writer("\n\n====================== CPU Registers =======================\n");
|
||||
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||
"R0 ", cpu_frame->r0,
|
||||
"R1 ", cpu_frame->r1,
|
||||
"R2 ", cpu_frame->r2,
|
||||
"R3 ", cpu_frame->r3);
|
||||
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||
"R12", cpu_frame->r12,
|
||||
"LR ", cpu_frame->lr,
|
||||
"PC ", cpu_frame->pc,
|
||||
"PSR", cpu_frame->spsr);
|
||||
}
|
||||
|
||||
__STATIC__ void fault_dump_stack(fault_info_t *info, size_t depth)
|
||||
{
|
||||
cpu_addr_t sp = info->sp_before_fault;
|
||||
|
||||
k_fault_log_writer("\nTASK STACK DUMP:\n");
|
||||
while (sp <= info->stack_limit && depth--) {
|
||||
k_fault_log_writer(" addr: %08x data: %08x\n", sp, (cpu_data_t)*(cpu_data_t *)sp);
|
||||
sp += sizeof(cpu_addr_t);
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC__ void fault_call_stack_backtrace(fault_info_t *info, size_t depth)
|
||||
{
|
||||
cpu_data_t value;
|
||||
cpu_addr_t sp = info->sp_before_fault;
|
||||
|
||||
if (info->is_stk_ovrf) {
|
||||
return;
|
||||
}
|
||||
|
||||
k_fault_log_writer("\n\n====================== Dump Call Stack =====================\n");
|
||||
|
||||
k_fault_log_writer(" %x\n", info->pc);
|
||||
|
||||
/* walk through the stack, check every content on stack whether is a instruction(code) */
|
||||
for (; sp < info->stack_limit && depth; sp += sizeof(cpu_addr_t)) {
|
||||
value = *((cpu_addr_t *)sp) - sizeof(cpu_addr_t);
|
||||
|
||||
/* if thumb, a instruction's first bit must be 1 */
|
||||
if (info->is_thumb && !(value & 1)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fault_is_code(info, value)) {
|
||||
k_fault_log_writer(" %x\n", value);
|
||||
--depth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC__ void fault_dump_task(fault_info_t *info)
|
||||
{
|
||||
k_task_t *task;
|
||||
|
||||
if (!info->is_on_task) {
|
||||
return;
|
||||
}
|
||||
|
||||
task = k_curr_task;
|
||||
k_fault_log_writer("\n\n====================== Fault on task =======================\n");
|
||||
k_fault_log_writer(" TASK NAME: %s\n", task->name);
|
||||
k_fault_log_writer(" STK BASE: %x\n", info->stack_start);
|
||||
k_fault_log_writer(" STK SIZE: %x\n", task->stk_size * sizeof(k_stack_t));
|
||||
k_fault_log_writer(" STK LIMIT: %x\n", info->stack_limit);
|
||||
|
||||
if (!info->is_stk_ovrf) {
|
||||
fault_dump_stack(info, K_FAULT_STACK_DUMP_DEPTH);
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC__ void fault_dump_information(fault_info_t *info)
|
||||
{
|
||||
k_fault_log_writer("\n\n================== Dump Fault Information ==================\n");
|
||||
k_fault_log_writer(" THUMB: %s\n", info->is_thumb ? "TRUE" : "FALSE");
|
||||
k_fault_log_writer(" ON TASK: %s\n", info->is_on_task? "TRUE" : "FALSE");
|
||||
k_fault_log_writer(" STK OVRF: %s\n", info->is_stk_ovrf? "TRUE" : "FALSE");
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
k_fault_log_writer(" EXT STK: %s\n", info->is_ext_stk_frm? "TRUE" : "FALSE");
|
||||
#endif
|
||||
|
||||
k_fault_log_writer(" PC: %08x\n", info->pc);
|
||||
k_fault_log_writer(" SP: %08x\n", info->sp_before_fault);
|
||||
k_fault_log_writer(" STK START: %08x\n", info->stack_start);
|
||||
k_fault_log_writer(" STK LIMIT: %08x\n", info->stack_limit);
|
||||
k_fault_log_writer(" COD START: %08x\n", info->code_start);
|
||||
k_fault_log_writer(" COD LIMIT: %08x\n", info->code_limit);
|
||||
}
|
||||
|
||||
__STATIC__ void fault_gather_information(cpu_data_t lr, fault_exc_frame_t *frame, fault_info_t *info)
|
||||
{
|
||||
info->is_thumb = fault_is_thumb(frame->cpu_frame.spsr);
|
||||
info->is_on_task = fault_is_on_task(lr);
|
||||
|
||||
info->pc = frame->cpu_frame.pc;
|
||||
|
||||
info->sp_before_fault = (cpu_addr_t)frame + sizeof(fault_cpu_frame_t);
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
info->is_ext_stk_frm = fault_is_extended_stack_frame(lr);
|
||||
|
||||
if (info->is_ext_stk_frm) {
|
||||
info->sp_before_fault += sizeof(fault_fpu_frame_t);
|
||||
}
|
||||
#endif
|
||||
|
||||
info->code_start = fault_code_start();
|
||||
info->code_limit = fault_code_limit();
|
||||
|
||||
if (info->is_on_task) {
|
||||
info->stack_start = (cpu_addr_t)k_curr_task->stk_base;
|
||||
info->stack_limit = info->stack_start + k_curr_task->stk_size * sizeof(k_task_t);
|
||||
} else {
|
||||
info->stack_start = fault_msp_start();
|
||||
info->stack_limit = fault_msp_limit();
|
||||
}
|
||||
|
||||
info->is_stk_ovrf = (info->sp_before_fault < info->stack_start || info->sp_before_fault > info->stack_limit);
|
||||
}
|
||||
|
||||
__KNL__ int fault_default_log_writer(const char *format, ...)
|
||||
{
|
||||
int len;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
len = vprintf(format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
__API__ void tos_fault_log_writer_set(k_fault_log_writer_t log_writer)
|
||||
{
|
||||
k_fault_log_writer = log_writer;
|
||||
}
|
||||
|
||||
__KNL__ void fault_backtrace(cpu_addr_t lr, fault_exc_frame_t *frame)
|
||||
{
|
||||
fault_info_t info;
|
||||
|
||||
fault_gather_information(lr, frame, &info);
|
||||
|
||||
fault_dump_information(&info);
|
||||
|
||||
fault_dump_task(&info);
|
||||
|
||||
fault_dump_cpu_frame(&frame->cpu_frame);
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
if (info.is_ext_stk_frm) {
|
||||
fault_dump_fpu_frame(&frame->fpu_frame);
|
||||
}
|
||||
#endif
|
||||
|
||||
fault_call_stack_backtrace(&info, K_FAULT_CALL_STACK_BACKTRACE_DEPTH);
|
||||
|
||||
cpu_fault_diagnosis();
|
||||
|
||||
fault_spin();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
struct arm_iframe {
|
||||
#if 0 // VFP
|
||||
uint32_t fpexc;
|
||||
#endif
|
||||
uint32_t r0;
|
||||
uint32_t r1;
|
||||
uint32_t r2;
|
||||
uint32_t r3;
|
||||
uint32_t r12;
|
||||
uint32_t lr;
|
||||
uint32_t pc;
|
||||
uint32_t spsr;
|
||||
};
|
||||
|
||||
struct arm_fault_frame {
|
||||
#if 0 // VFP
|
||||
uint32_t fpexc;
|
||||
#endif
|
||||
|
||||
uint32_t r[13];
|
||||
uint32_t lr;
|
||||
uint32_t pc;
|
||||
uint32_t spsr;
|
||||
};
|
||||
|
||||
#define CPSR_MODE_MASK 0x1f
|
||||
#define CPSR_MODE_USR 0x10
|
||||
#define CPSR_MODE_FIQ 0x11
|
||||
#define CPSR_MODE_IRQ 0x12
|
||||
#define CPSR_MODE_SVC 0x13
|
||||
#define CPSR_MODE_MON 0x16
|
||||
#define CPSR_MODE_ABT 0x17
|
||||
#define CPSR_MODE_UND 0x1b
|
||||
#define CPSR_MODE_SYS 0x1f
|
||||
|
||||
static void dump_fault_frame(struct arm_fault_frame *frame)
|
||||
{
|
||||
printf("r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n", frame->r[0], frame->r[1], frame->r[2], frame->r[3]);
|
||||
printf("r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n", frame->r[4], frame->r[5], frame->r[6], frame->r[7]);
|
||||
printf("r8 0x%08x r9 0x%08x r10 0x%08x r11 0x%08x\n", frame->r[8], frame->r[9], frame->r[10], frame->r[11]);
|
||||
printf("r12 0x%08x pc 0x%08x\n", frame->r[12], frame->pc);
|
||||
printf("spsr 0x%08x\n", frame->spsr);
|
||||
|
||||
while (1);
|
||||
}
|
||||
|
||||
static void dump_iframe(struct arm_iframe *frame)
|
||||
{
|
||||
printf("r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n", frame->r0, frame->r1, frame->r2, frame->r3);
|
||||
printf("r12 0x%08x pc 0x%08x\n", frame->r12, frame->pc);
|
||||
printf("spsr 0x%08x\n", frame->spsr);
|
||||
}
|
||||
|
||||
static void exception_die_iframe(struct arm_iframe *frame, const char *msg)
|
||||
{
|
||||
printf("%s", msg);
|
||||
dump_iframe(frame);
|
||||
|
||||
while (1);
|
||||
}
|
||||
|
||||
void arm_undefined_handler(struct arm_iframe *frame)
|
||||
{
|
||||
printf("undefined\r\n");
|
||||
|
||||
/* look at the undefined instruction, figure out if it's something we can handle */
|
||||
int in_thumb = frame->spsr & (1<<5);
|
||||
if (in_thumb) {
|
||||
frame->pc -= 2;
|
||||
} else {
|
||||
frame->pc -= 4;
|
||||
}
|
||||
|
||||
uint32_t opcode = *(uint32_t *)frame->pc;
|
||||
printf("undefined opcode 0x%x\n", opcode);
|
||||
|
||||
#if 0 // VFP
|
||||
if (in_thumb) {
|
||||
/* look for a 32bit thumb instruction */
|
||||
if (opcode & 0x0000e800) {
|
||||
/* swap the 16bit words */
|
||||
opcode = (opcode >> 16) | (opcode << 16);
|
||||
}
|
||||
|
||||
if (((opcode & 0xec000e00) == 0xec000a00) || // vfp
|
||||
((opcode & 0xef000000) == 0xef000000) || // advanced simd data processing
|
||||
((opcode & 0xff100000) == 0xf9000000)) { // VLD
|
||||
|
||||
//printf("vfp/neon thumb instruction 0x%08x at 0x%x\n", opcode, frame->pc);
|
||||
goto fpu;
|
||||
}
|
||||
} else {
|
||||
/* look for arm vfp/neon coprocessor instructions */
|
||||
if (((opcode & 0x0c000e00) == 0x0c000a00) || // vfp
|
||||
((opcode & 0xfe000000) == 0xf2000000) || // advanced simd data processing
|
||||
((opcode & 0xff100000) == 0xf4000000)) { // VLD
|
||||
//printf("vfp/neon arm instruction 0x%08x at 0x%x\n", opcode, frame->pc);
|
||||
goto fpu;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
exception_die_iframe(frame, "undefined abort, halting\n");
|
||||
return;
|
||||
|
||||
#if 0 // VFP
|
||||
fpu:
|
||||
arm_fpu_undefined_instruction(frame);
|
||||
#endif
|
||||
}
|
||||
|
||||
void arm_data_abort_handler(struct arm_fault_frame *frame)
|
||||
{
|
||||
printf("data abort!!\r\n");
|
||||
dump_fault_frame(frame);
|
||||
}
|
||||
|
||||
void arm_prefetch_abort_handler(struct arm_fault_frame *frame)
|
||||
{
|
||||
printf("prefetch abort!!\r\n");
|
||||
dump_fault_frame(frame);
|
||||
}
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos_k.h"
|
||||
|
||||
__STATIC__ gic_data_t gic_data[GIC_NRS];
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t gic_base_get(void)
|
||||
{
|
||||
/* read CBAR */
|
||||
return (ARM_MRC(15, 4, 15, 0, 0) & 0xFFFF0000UL);
|
||||
}
|
||||
|
||||
__STATIC__ void gic_data_init(gic_data_t *gic)
|
||||
{
|
||||
cpu_addr_t gic_base;
|
||||
|
||||
gic_base = gic_base_get();
|
||||
|
||||
gic->dist = (gic_dist_t *)(gic_base + GICD_OFFSET); /* distributor */
|
||||
gic->cpu = (gic_cpu_t *)(gic_base + GICC_OFFSET); /* cpu interface */
|
||||
}
|
||||
|
||||
__STATIC__ void gic_dist_init(gic_dist_t *gic_dist)
|
||||
{
|
||||
uint32_t i = 0, int_id_max = 0;
|
||||
|
||||
// let's make it simple here, maybe SMP someday, but not now
|
||||
#define IT_LINES_NUMBER(d_type) ((d_type) & 0x1FUL)
|
||||
int_id_max = IT_LINES_NUMBER(gic_dist->D_TYPER) + 1;
|
||||
|
||||
/* Disable all PPI, SGI and SPI */
|
||||
for (i = 0; i < int_id_max; ++i) {
|
||||
gic_dist->D_ICENABLER[i] = 0xFFFFFFFFUL;
|
||||
}
|
||||
|
||||
/* Enable group0 distribution */
|
||||
gic_dist->D_CTLR = 1UL;
|
||||
}
|
||||
|
||||
__STATIC__ void gic_cpu_init(gic_cpu_t *gic_cpu)
|
||||
{
|
||||
/* Make all interrupts have higher priority */
|
||||
gic_cpu->C_PMR = (0xFFUL << (8 - GIC_PRIO_BITS)) & 0xFFUL;
|
||||
|
||||
/* No subpriority, all priority level allows preemption */
|
||||
gic_cpu->C_BPR = 7 - GIC_PRIO_BITS;
|
||||
|
||||
/* Enable group0 signaling */
|
||||
gic_cpu->C_CTLR = 1UL;
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ gic_data_t *gic_get(uint32_t gic_nr)
|
||||
{
|
||||
gic_data_t *gic;
|
||||
|
||||
if (gic_nr >= GIC_NRS) {
|
||||
return K_NULL;
|
||||
}
|
||||
|
||||
gic = &gic_data[gic_nr];
|
||||
|
||||
if (gic->cpu && gic->dist) {
|
||||
return gic;
|
||||
}
|
||||
|
||||
return K_NULL;
|
||||
}
|
||||
|
||||
__KNL__ uint32_t gic_interrupt_id_get(uint32_t gic_nr)
|
||||
{
|
||||
gic_data_t *gic = gic_get(gic_nr);
|
||||
|
||||
if (gic) {
|
||||
#define INTERRUPT_ID(iar) ((iar) & 0x3FFUL)
|
||||
return INTERRUPT_ID(gic->cpu->C_IAR);
|
||||
}
|
||||
|
||||
return (uint32_t)-1;
|
||||
}
|
||||
|
||||
__KNL__ void gic_interrupt_end(uint32_t gic_nr, uint32_t vector)
|
||||
{
|
||||
gic_data_t *gic = gic_get(gic_nr);
|
||||
|
||||
if (gic) {
|
||||
gic->cpu->C_EOIR = vector;
|
||||
}
|
||||
}
|
||||
|
||||
__KNL__ int gic_init(uint32_t gic_nr)
|
||||
{
|
||||
gic_data_t *gic;
|
||||
|
||||
if (gic_nr >= GIC_NRS) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
gic = &gic_data[gic_nr];
|
||||
|
||||
gic_data_init(gic);
|
||||
gic_dist_init(gic->dist);
|
||||
gic_cpu_init(gic->cpu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__KNL__ void gic_interrupt_enable(uint32_t gic_nr, uint32_t vector)
|
||||
{
|
||||
int reg;
|
||||
uint32_t mask;
|
||||
gic_data_t *gic;
|
||||
|
||||
gic = gic_get(gic_nr);
|
||||
if (gic) {
|
||||
reg = vector / 32;
|
||||
mask = 1ULL << (vector % 32);
|
||||
|
||||
gic->dist->D_ISENABLER[reg] = mask;
|
||||
}
|
||||
}
|
||||
|
||||
__KNL__ void gic_interrupt_disable(uint32_t gic_nr, uint32_t vector)
|
||||
{
|
||||
int reg;
|
||||
uint32_t mask;
|
||||
gic_data_t *gic;
|
||||
|
||||
gic = gic_get(gic_nr);
|
||||
if (gic) {
|
||||
reg = vector / 32;
|
||||
mask = 1ULL << (vector % 32);
|
||||
gic->dist->D_ICENABLER[reg] = mask;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos_k.h"
|
||||
|
||||
__STATIC__ int_handle_t int_handle_table[INTERRUPT_MAX];
|
||||
|
||||
__KNL__ void interrupt_irq(int_frame_t *int_frame)
|
||||
{
|
||||
uint32_t vector;
|
||||
int_handle_t *handle;
|
||||
|
||||
vector = gic_interrupt_id_get(0u);
|
||||
|
||||
if (vector > INTERRUPT_MAX || vector == (uint32_t)-1) {
|
||||
return;
|
||||
}
|
||||
|
||||
handle = &int_handle_table[vector];
|
||||
if (handle->handler) {
|
||||
handle->handler(handle->arg);
|
||||
}
|
||||
|
||||
gic_interrupt_end(0u, vector);
|
||||
}
|
||||
|
||||
__KNL__ int interrupt_init(void)
|
||||
{
|
||||
gic_init(0u);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__API__ int tos_interrupt_handler_register(uint32_t vector, int_handler_t handler, void *arg)
|
||||
{
|
||||
if (vector < INTERRUPT_MAX) {
|
||||
int_handle_table[vector].handler = handler;
|
||||
int_handle_table[vector].arg = arg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
__API__ void tos_interrupt_enable(uint32_t vector)
|
||||
{
|
||||
gic_interrupt_enable(0u, vector);
|
||||
}
|
||||
|
||||
__API__ void tos_interrupt_disable(uint32_t vector)
|
||||
{
|
||||
gic_interrupt_disable(0u, vector);
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
#include "tos_k.h"
|
||||
#include "imx6ul.h"
|
||||
|
||||
/* set the core clock to 528MHz */
|
||||
void clock_init(void)
|
||||
{
|
||||
unsigned int reg = 0;
|
||||
|
||||
if ((((CCM->CCSR) >> 2) & 0x1) == 0) {
|
||||
CCM->CCSR &= ~(1 << 8);
|
||||
CCM->CCSR |= (1 << 2);
|
||||
}
|
||||
|
||||
CCM_ANALOG->PLL_ARM = (1 << 13) | ((88 << 0) & 0X7F);
|
||||
CCM->CCSR &= ~(1 << 2);
|
||||
CCM->CACRR = 1;
|
||||
|
||||
reg = CCM_ANALOG->PFD_528;
|
||||
reg &= ~(0X3F3F3F3F);
|
||||
reg |= 32 << 24;
|
||||
reg |= 24 << 16;
|
||||
reg |= 16 << 8;
|
||||
reg |= 27 << 0;
|
||||
CCM_ANALOG->PFD_528 = reg;
|
||||
|
||||
reg = 0;
|
||||
reg = CCM_ANALOG->PFD_480;
|
||||
reg &= ~(0X3F3F3F3F);
|
||||
reg |= 19 << 24;
|
||||
reg |= 17 << 16;
|
||||
reg |= 16 << 8;
|
||||
reg |= 12 << 0;
|
||||
CCM_ANALOG->PFD_480 = reg;
|
||||
|
||||
CCM->CBCMR &= ~(3 << 18);
|
||||
CCM->CBCMR |= (1 << 18);
|
||||
CCM->CBCDR &= ~(1 << 25);
|
||||
while(CCM->CDHIPR & (1 << 5)) {
|
||||
;
|
||||
}
|
||||
|
||||
CCM->CBCDR &= ~(3 << 8);
|
||||
CCM->CBCDR |= 1 << 8;
|
||||
|
||||
CCM->CSCMR1 &= ~(1 << 6);
|
||||
CCM->CSCMR1 &= ~(7 << 0);
|
||||
|
||||
CCM->CSCDR1 &= ~(1 << 6);
|
||||
CCM->CSCDR1 &= ~0X3F;
|
||||
}
|
||||
|
||||
void clock_enable(void)
|
||||
{
|
||||
CCM->CCGR0 = 0XFFFFFFFF;
|
||||
CCM->CCGR1 = 0XFFFFFFFF;
|
||||
CCM->CCGR2 = 0XFFFFFFFF;
|
||||
CCM->CCGR3 = 0XFFFFFFFF;
|
||||
CCM->CCGR4 = 0XFFFFFFFF;
|
||||
CCM->CCGR5 = 0XFFFFFFFF;
|
||||
CCM->CCGR6 = 0XFFFFFFFF;
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos_k.h"
|
||||
#include "imx6ul.h"
|
||||
|
||||
__KNL__ void chip_init(void)
|
||||
{
|
||||
clock_init();
|
||||
clock_enable();
|
||||
systick_init(k_cpu_tick_per_second);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,25 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _PLATFORM_H_
|
||||
#define _PLATFORM_H_
|
||||
|
||||
#define INTERRUPT_MAX 128
|
||||
#define KERNEL_BASE 0X87800000
|
||||
|
||||
#endif /* _CHIP_H_ */
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GIC_H_
|
||||
#define _GIC_H_
|
||||
|
||||
#define GICD_OFFSET 0x1000
|
||||
#define GICC_OFFSET 0x2000
|
||||
#define GIC_PRIO_BITS 5 /**< Number of Bits used for Priority Levels */
|
||||
#define GIC_NRS 1 /**< how many gic on this chip? */
|
||||
|
||||
#endif /* _GIC_H_ */
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _CLOCK_H_
|
||||
#define _CLOCK_H_
|
||||
|
||||
void clock_init(void);
|
||||
void clock_enable(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,723 @@
|
|||
#ifndef __CORTEX_CA7_H
|
||||
#define __CORTEX_CA7_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#define FORCEDINLINE __attribute__((always_inline))
|
||||
#define __ASM __asm /* GNU C语言内嵌汇编关键字 */
|
||||
#define __INLINE inline /* GNU内联关键字 */
|
||||
#define __STATIC_INLINE static inline
|
||||
|
||||
|
||||
#define __IM volatile const /* 只读 */
|
||||
#define __OM volatile /* 只写 */
|
||||
#define __IOM volatile /* 读写 */
|
||||
#define __STRINGIFY(x) #x
|
||||
|
||||
/* C语言实现MCR指令 */
|
||||
#define __MCR(coproc, opcode_1, src, CRn, CRm, opcode_2) \
|
||||
__ASM volatile ("MCR " __STRINGIFY(p##coproc) ", " __STRINGIFY(opcode_1) ", " \
|
||||
"%0, " __STRINGIFY(c##CRn) ", " __STRINGIFY(c##CRm) ", " \
|
||||
__STRINGIFY(opcode_2) \
|
||||
: : "r" (src) )
|
||||
|
||||
/* C语言实现MRC指令 */
|
||||
#define __MRC(coproc, opcode_1, CRn, CRm, opcode_2) \
|
||||
({ \
|
||||
uint32_t __dst; \
|
||||
__ASM volatile ("MRC " __STRINGIFY(p##coproc) ", " __STRINGIFY(opcode_1) ", " \
|
||||
"%0, " __STRINGIFY(c##CRn) ", " __STRINGIFY(c##CRm) ", " \
|
||||
__STRINGIFY(opcode_2) \
|
||||
: "=r" (__dst) ); \
|
||||
__dst; \
|
||||
})
|
||||
|
||||
/* 其他一些C语言内嵌汇编 */
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_APSR(uint32_t apsr)
|
||||
{
|
||||
__ASM volatile ("MSR apsr, %0" : : "r" (apsr) : "cc");
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CPSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, cpsr" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CPSR(uint32_t cpsr)
|
||||
{
|
||||
__ASM volatile ("MSR cpsr, %0" : : "r" (cpsr) : "cc");
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPEXC(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("VMRS %0, fpexc" : "=r" (result) );
|
||||
return result;
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPEXC(uint32_t fpexc)
|
||||
{
|
||||
__ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc));
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* 一些内核寄存器定义和抽象
|
||||
定义如下几个内核寄存器:
|
||||
- CPSR
|
||||
- CP15
|
||||
******************************************************************************/
|
||||
|
||||
/* CPSR寄存器
|
||||
* 参考资料:ARM Cortex-A(armV7)编程手册V4.0.pdf P46
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t M:5; /*!< bit: 0.. 4 Mode field */
|
||||
uint32_t T:1; /*!< bit: 5 Thumb execution state bit */
|
||||
uint32_t F:1; /*!< bit: 6 FIQ mask bit */
|
||||
uint32_t I:1; /*!< bit: 7 IRQ mask bit */
|
||||
uint32_t A:1; /*!< bit: 8 Asynchronous abort mask bit */
|
||||
uint32_t E:1; /*!< bit: 9 Endianness execution state bit */
|
||||
uint32_t IT1:6; /*!< bit: 10..15 If-Then execution state bits 2-7 */
|
||||
uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
|
||||
uint32_t _reserved0:4; /*!< bit: 20..23 Reserved */
|
||||
uint32_t J:1; /*!< bit: 24 Jazelle bit */
|
||||
uint32_t IT0:2; /*!< bit: 25..26 If-Then execution state bits 0-1 */
|
||||
uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
|
||||
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} CPSR_Type;
|
||||
|
||||
|
||||
/* CP15的SCTLR寄存器
|
||||
* 参考资料:Cortex-A7 Technical ReferenceManua.pdf P105
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t M:1; /*!< bit: 0 MMU enable */
|
||||
uint32_t A:1; /*!< bit: 1 Alignment check enable */
|
||||
uint32_t C:1; /*!< bit: 2 Cache enable */
|
||||
uint32_t _reserved0:2; /*!< bit: 3.. 4 Reserved */
|
||||
uint32_t CP15BEN:1; /*!< bit: 5 CP15 barrier enable */
|
||||
uint32_t _reserved1:1; /*!< bit: 6 Reserved */
|
||||
uint32_t B:1; /*!< bit: 7 Endianness model */
|
||||
uint32_t _reserved2:2; /*!< bit: 8.. 9 Reserved */
|
||||
uint32_t SW:1; /*!< bit: 10 SWP and SWPB enable */
|
||||
uint32_t Z:1; /*!< bit: 11 Branch prediction enable */
|
||||
uint32_t I:1; /*!< bit: 12 Instruction cache enable */
|
||||
uint32_t V:1; /*!< bit: 13 Vectors bit */
|
||||
uint32_t RR:1; /*!< bit: 14 Round Robin select */
|
||||
uint32_t _reserved3:2; /*!< bit:15..16 Reserved */
|
||||
uint32_t HA:1; /*!< bit: 17 Hardware Access flag enable */
|
||||
uint32_t _reserved4:1; /*!< bit: 18 Reserved */
|
||||
uint32_t WXN:1; /*!< bit: 19 Write permission implies XN */
|
||||
uint32_t UWXN:1; /*!< bit: 20 Unprivileged write permission implies PL1 XN */
|
||||
uint32_t FI:1; /*!< bit: 21 Fast interrupts configuration enable */
|
||||
uint32_t U:1; /*!< bit: 22 Alignment model */
|
||||
uint32_t _reserved5:1; /*!< bit: 23 Reserved */
|
||||
uint32_t VE:1; /*!< bit: 24 Interrupt Vectors Enable */
|
||||
uint32_t EE:1; /*!< bit: 25 Exception Endianness */
|
||||
uint32_t _reserved6:1; /*!< bit: 26 Reserved */
|
||||
uint32_t NMFI:1; /*!< bit: 27 Non-maskable FIQ (NMFI) support */
|
||||
uint32_t TRE:1; /*!< bit: 28 TEX remap enable. */
|
||||
uint32_t AFE:1; /*!< bit: 29 Access flag enable */
|
||||
uint32_t TE:1; /*!< bit: 30 Thumb Exception enable */
|
||||
uint32_t _reserved7:1; /*!< bit: 31 Reserved */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} SCTLR_Type;
|
||||
|
||||
/* CP15 寄存器SCTLR各个位定义 */
|
||||
#define SCTLR_TE_Pos 30U /*!< SCTLR: TE Position */
|
||||
#define SCTLR_TE_Msk (1UL << SCTLR_TE_Pos) /*!< SCTLR: TE Mask */
|
||||
|
||||
#define SCTLR_AFE_Pos 29U /*!< SCTLR: AFE Position */
|
||||
#define SCTLR_AFE_Msk (1UL << SCTLR_AFE_Pos) /*!< SCTLR: AFE Mask */
|
||||
|
||||
#define SCTLR_TRE_Pos 28U /*!< SCTLR: TRE Position */
|
||||
#define SCTLR_TRE_Msk (1UL << SCTLR_TRE_Pos) /*!< SCTLR: TRE Mask */
|
||||
|
||||
#define SCTLR_NMFI_Pos 27U /*!< SCTLR: NMFI Position */
|
||||
#define SCTLR_NMFI_Msk (1UL << SCTLR_NMFI_Pos) /*!< SCTLR: NMFI Mask */
|
||||
|
||||
#define SCTLR_EE_Pos 25U /*!< SCTLR: EE Position */
|
||||
#define SCTLR_EE_Msk (1UL << SCTLR_EE_Pos) /*!< SCTLR: EE Mask */
|
||||
|
||||
#define SCTLR_VE_Pos 24U /*!< SCTLR: VE Position */
|
||||
#define SCTLR_VE_Msk (1UL << SCTLR_VE_Pos) /*!< SCTLR: VE Mask */
|
||||
|
||||
#define SCTLR_U_Pos 22U /*!< SCTLR: U Position */
|
||||
#define SCTLR_U_Msk (1UL << SCTLR_U_Pos) /*!< SCTLR: U Mask */
|
||||
|
||||
#define SCTLR_FI_Pos 21U /*!< SCTLR: FI Position */
|
||||
#define SCTLR_FI_Msk (1UL << SCTLR_FI_Pos) /*!< SCTLR: FI Mask */
|
||||
|
||||
#define SCTLR_UWXN_Pos 20U /*!< SCTLR: UWXN Position */
|
||||
#define SCTLR_UWXN_Msk (1UL << SCTLR_UWXN_Pos) /*!< SCTLR: UWXN Mask */
|
||||
|
||||
#define SCTLR_WXN_Pos 19U /*!< SCTLR: WXN Position */
|
||||
#define SCTLR_WXN_Msk (1UL << SCTLR_WXN_Pos) /*!< SCTLR: WXN Mask */
|
||||
|
||||
#define SCTLR_HA_Pos 17U /*!< SCTLR: HA Position */
|
||||
#define SCTLR_HA_Msk (1UL << SCTLR_HA_Pos) /*!< SCTLR: HA Mask */
|
||||
|
||||
#define SCTLR_RR_Pos 14U /*!< SCTLR: RR Position */
|
||||
#define SCTLR_RR_Msk (1UL << SCTLR_RR_Pos) /*!< SCTLR: RR Mask */
|
||||
|
||||
#define SCTLR_V_Pos 13U /*!< SCTLR: V Position */
|
||||
#define SCTLR_V_Msk (1UL << SCTLR_V_Pos) /*!< SCTLR: V Mask */
|
||||
|
||||
#define SCTLR_I_Pos 12U /*!< SCTLR: I Position */
|
||||
#define SCTLR_I_Msk (1UL << SCTLR_I_Pos) /*!< SCTLR: I Mask */
|
||||
|
||||
#define SCTLR_Z_Pos 11U /*!< SCTLR: Z Position */
|
||||
#define SCTLR_Z_Msk (1UL << SCTLR_Z_Pos) /*!< SCTLR: Z Mask */
|
||||
|
||||
#define SCTLR_SW_Pos 10U /*!< SCTLR: SW Position */
|
||||
#define SCTLR_SW_Msk (1UL << SCTLR_SW_Pos) /*!< SCTLR: SW Mask */
|
||||
|
||||
#define SCTLR_B_Pos 7U /*!< SCTLR: B Position */
|
||||
#define SCTLR_B_Msk (1UL << SCTLR_B_Pos) /*!< SCTLR: B Mask */
|
||||
|
||||
#define SCTLR_CP15BEN_Pos 5U /*!< SCTLR: CP15BEN Position */
|
||||
#define SCTLR_CP15BEN_Msk (1UL << SCTLR_CP15BEN_Pos) /*!< SCTLR: CP15BEN Mask */
|
||||
|
||||
#define SCTLR_C_Pos 2U /*!< SCTLR: C Position */
|
||||
#define SCTLR_C_Msk (1UL << SCTLR_C_Pos) /*!< SCTLR: C Mask */
|
||||
|
||||
#define SCTLR_A_Pos 1U /*!< SCTLR: A Position */
|
||||
#define SCTLR_A_Msk (1UL << SCTLR_A_Pos) /*!< SCTLR: A Mask */
|
||||
|
||||
#define SCTLR_M_Pos 0U /*!< SCTLR: M Position */
|
||||
#define SCTLR_M_Msk (1UL << SCTLR_M_Pos) /*!< SCTLR: M Mask */
|
||||
|
||||
/* CP15的ACTLR寄存器
|
||||
* 参考资料:Cortex-A7 Technical ReferenceManua.pdf P113
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t _reserved0:6; /*!< bit: 0.. 5 Reserved */
|
||||
uint32_t SMP:1; /*!< bit: 6 Enables coherent requests to the processor */
|
||||
uint32_t _reserved1:3; /*!< bit: 7.. 9 Reserved */
|
||||
uint32_t DODMBS:1; /*!< bit: 10 Disable optimized data memory barrier behavior */
|
||||
uint32_t L2RADIS:1; /*!< bit: 11 L2 Data Cache read-allocate mode disable */
|
||||
uint32_t L1RADIS:1; /*!< bit: 12 L1 Data Cache read-allocate mode disable */
|
||||
uint32_t L1PCTL:2; /*!< bit:13..14 L1 Data prefetch control */
|
||||
uint32_t DDVM:1; /*!< bit: 15 Disable Distributed Virtual Memory (DVM) transactions */
|
||||
uint32_t _reserved3:12; /*!< bit:16..27 Reserved */
|
||||
uint32_t DDI:1; /*!< bit: 28 Disable dual issue */
|
||||
uint32_t _reserved7:3; /*!< bit:29..31 Reserved */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} ACTLR_Type;
|
||||
|
||||
#define ACTLR_DDI_Pos 28U /*!< ACTLR: DDI Position */
|
||||
#define ACTLR_DDI_Msk (1UL << ACTLR_DDI_Pos) /*!< ACTLR: DDI Mask */
|
||||
|
||||
#define ACTLR_DDVM_Pos 15U /*!< ACTLR: DDVM Position */
|
||||
#define ACTLR_DDVM_Msk (1UL << ACTLR_DDVM_Pos) /*!< ACTLR: DDVM Mask */
|
||||
|
||||
#define ACTLR_L1PCTL_Pos 13U /*!< ACTLR: L1PCTL Position */
|
||||
#define ACTLR_L1PCTL_Msk (3UL << ACTLR_L1PCTL_Pos) /*!< ACTLR: L1PCTL Mask */
|
||||
|
||||
#define ACTLR_L1RADIS_Pos 12U /*!< ACTLR: L1RADIS Position */
|
||||
#define ACTLR_L1RADIS_Msk (1UL << ACTLR_L1RADIS_Pos) /*!< ACTLR: L1RADIS Mask */
|
||||
|
||||
#define ACTLR_L2RADIS_Pos 11U /*!< ACTLR: L2RADIS Position */
|
||||
#define ACTLR_L2RADIS_Msk (1UL << ACTLR_L2RADIS_Pos) /*!< ACTLR: L2RADIS Mask */
|
||||
|
||||
#define ACTLR_DODMBS_Pos 10U /*!< ACTLR: DODMBS Position */
|
||||
#define ACTLR_DODMBS_Msk (1UL << ACTLR_DODMBS_Pos) /*!< ACTLR: DODMBS Mask */
|
||||
|
||||
#define ACTLR_SMP_Pos 6U /*!< ACTLR: SMP Position */
|
||||
#define ACTLR_SMP_Msk (1UL << ACTLR_SMP_Pos) /*!< ACTLR: SMP Mask */
|
||||
|
||||
|
||||
/* CP15的CPACR寄存器
|
||||
* 参考资料:Cortex-A7 Technical ReferenceManua.pdf P115
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t _reserved0:20; /*!< bit: 0..19 Reserved */
|
||||
uint32_t cp10:2; /*!< bit:20..21 Access rights for coprocessor 10 */
|
||||
uint32_t cp11:2; /*!< bit:22..23 Access rights for coprocessor 11 */
|
||||
uint32_t _reserved1:6; /*!< bit:24..29 Reserved */
|
||||
uint32_t D32DIS:1; /*!< bit: 30 Disable use of registers D16-D31 of the VFP register file */
|
||||
uint32_t ASEDIS:1; /*!< bit: 31 Disable Advanced SIMD Functionality */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} CPACR_Type;
|
||||
|
||||
#define CPACR_ASEDIS_Pos 31U /*!< CPACR: ASEDIS Position */
|
||||
#define CPACR_ASEDIS_Msk (1UL << CPACR_ASEDIS_Pos) /*!< CPACR: ASEDIS Mask */
|
||||
|
||||
#define CPACR_D32DIS_Pos 30U /*!< CPACR: D32DIS Position */
|
||||
#define CPACR_D32DIS_Msk (1UL << CPACR_D32DIS_Pos) /*!< CPACR: D32DIS Mask */
|
||||
|
||||
#define CPACR_cp11_Pos 22U /*!< CPACR: cp11 Position */
|
||||
#define CPACR_cp11_Msk (3UL << CPACR_cp11_Pos) /*!< CPACR: cp11 Mask */
|
||||
|
||||
#define CPACR_cp10_Pos 20U /*!< CPACR: cp10 Position */
|
||||
#define CPACR_cp10_Msk (3UL << CPACR_cp10_Pos) /*!< CPACR: cp10 Mask */
|
||||
|
||||
|
||||
/* CP15的DFSR寄存器
|
||||
* 参考资料:Cortex-A7 Technical ReferenceManua.pdf P128
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t FS0:4; /*!< bit: 0.. 3 Fault Status bits bit 0-3 */
|
||||
uint32_t Domain:4; /*!< bit: 4.. 7 Fault on which domain */
|
||||
uint32_t _reserved0:2; /*!< bit: 8.. 9 Reserved */
|
||||
uint32_t FS1:1; /*!< bit: 10 Fault Status bits bit 4 */
|
||||
uint32_t WnR:1; /*!< bit: 11 Write not Read bit */
|
||||
uint32_t ExT:1; /*!< bit: 12 External abort type */
|
||||
uint32_t CM:1; /*!< bit: 13 Cache maintenance fault */
|
||||
uint32_t _reserved1:18; /*!< bit:14..31 Reserved */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} DFSR_Type;
|
||||
|
||||
#define DFSR_CM_Pos 13U /*!< DFSR: CM Position */
|
||||
#define DFSR_CM_Msk (1UL << DFSR_CM_Pos) /*!< DFSR: CM Mask */
|
||||
|
||||
#define DFSR_Ext_Pos 12U /*!< DFSR: Ext Position */
|
||||
#define DFSR_Ext_Msk (1UL << DFSR_Ext_Pos) /*!< DFSR: Ext Mask */
|
||||
|
||||
#define DFSR_WnR_Pos 11U /*!< DFSR: WnR Position */
|
||||
#define DFSR_WnR_Msk (1UL << DFSR_WnR_Pos) /*!< DFSR: WnR Mask */
|
||||
|
||||
#define DFSR_FS1_Pos 10U /*!< DFSR: FS1 Position */
|
||||
#define DFSR_FS1_Msk (1UL << DFSR_FS1_Pos) /*!< DFSR: FS1 Mask */
|
||||
|
||||
#define DFSR_Domain_Pos 4U /*!< DFSR: Domain Position */
|
||||
#define DFSR_Domain_Msk (0xFUL << DFSR_Domain_Pos) /*!< DFSR: Domain Mask */
|
||||
|
||||
#define DFSR_FS0_Pos 0U /*!< DFSR: FS0 Position */
|
||||
#define DFSR_FS0_Msk (0xFUL << DFSR_FS0_Pos) /*!< DFSR: FS0 Mask */
|
||||
|
||||
|
||||
/* CP15的IFSR寄存器
|
||||
* 参考资料:Cortex-A7 Technical ReferenceManua.pdf P131
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t FS0:4; /*!< bit: 0.. 3 Fault Status bits bit 0-3 */
|
||||
uint32_t _reserved0:6; /*!< bit: 4.. 9 Reserved */
|
||||
uint32_t FS1:1; /*!< bit: 10 Fault Status bits bit 4 */
|
||||
uint32_t _reserved1:1; /*!< bit: 11 Reserved */
|
||||
uint32_t ExT:1; /*!< bit: 12 External abort type */
|
||||
uint32_t _reserved2:19; /*!< bit:13..31 Reserved */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} IFSR_Type;
|
||||
|
||||
#define IFSR_ExT_Pos 12U /*!< IFSR: ExT Position */
|
||||
#define IFSR_ExT_Msk (1UL << IFSR_ExT_Pos) /*!< IFSR: ExT Mask */
|
||||
|
||||
#define IFSR_FS1_Pos 10U /*!< IFSR: FS1 Position */
|
||||
#define IFSR_FS1_Msk (1UL << IFSR_FS1_Pos) /*!< IFSR: FS1 Mask */
|
||||
|
||||
#define IFSR_FS0_Pos 0U /*!< IFSR: FS0 Position */
|
||||
#define IFSR_FS0_Msk (0xFUL << IFSR_FS0_Pos) /*!< IFSR: FS0 Mask */
|
||||
|
||||
|
||||
/* CP15的ISR寄存器
|
||||
* 参考资料:ARM ArchitectureReference Manual ARMv7-A and ARMv7-R edition.pdf P1640
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t _reserved0:6; /*!< bit: 0.. 5 Reserved */
|
||||
uint32_t F:1; /*!< bit: 6 FIQ pending bit */
|
||||
uint32_t I:1; /*!< bit: 7 IRQ pending bit */
|
||||
uint32_t A:1; /*!< bit: 8 External abort pending bit */
|
||||
uint32_t _reserved1:23; /*!< bit:14..31 Reserved */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} ISR_Type;
|
||||
|
||||
#define ISR_A_Pos 13U /*!< ISR: A Position */
|
||||
#define ISR_A_Msk (1UL << ISR_A_Pos) /*!< ISR: A Mask */
|
||||
|
||||
#define ISR_I_Pos 12U /*!< ISR: I Position */
|
||||
#define ISR_I_Msk (1UL << ISR_I_Pos) /*!< ISR: I Mask */
|
||||
|
||||
#define ISR_F_Pos 11U /*!< ISR: F Position */
|
||||
#define ISR_F_Msk (1UL << ISR_F_Pos) /*!< ISR: F Mask */
|
||||
|
||||
|
||||
/* Mask and shift a bit field value for use in a register bit range. */
|
||||
#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
|
||||
|
||||
/* Mask and shift a register value to extract a bit filed value. */
|
||||
#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* CP15 访问函数
|
||||
******************************************************************************/
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE uint32_t __get_SCTLR(void)
|
||||
{
|
||||
return __MRC(15, 0, 1, 0, 0);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE void __set_SCTLR(uint32_t sctlr)
|
||||
{
|
||||
__MCR(15, 0, sctlr, 1, 0, 0);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE uint32_t __get_ACTLR(void)
|
||||
{
|
||||
return __MRC(15, 0, 1, 0, 1);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE void __set_ACTLR(uint32_t actlr)
|
||||
{
|
||||
__MCR(15, 0, actlr, 1, 0, 1);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE uint32_t __get_CPACR(void)
|
||||
{
|
||||
return __MRC(15, 0, 1, 0, 2);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE void __set_CPACR(uint32_t cpacr)
|
||||
{
|
||||
__MCR(15, 0, cpacr, 1, 0, 2);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE uint32_t __get_TTBR0(void)
|
||||
{
|
||||
return __MRC(15, 0, 2, 0, 0);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE void __set_TTBR0(uint32_t ttbr0)
|
||||
{
|
||||
__MCR(15, 0, ttbr0, 2, 0, 0);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE uint32_t __get_TTBR1(void)
|
||||
{
|
||||
return __MRC(15, 0, 2, 0, 1);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE void __set_TTBR1(uint32_t ttbr1)
|
||||
{
|
||||
__MCR(15, 0, ttbr1, 2, 0, 1);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE uint32_t __get_TTBCR(void)
|
||||
{
|
||||
return __MRC(15, 0, 2, 0, 2);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE void __set_TTBCR(uint32_t ttbcr)
|
||||
{
|
||||
__MCR(15, 0, ttbcr, 2, 0, 2);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE uint32_t __get_DACR(void)
|
||||
{
|
||||
return __MRC(15, 0, 3, 0, 0);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE void __set_DACR(uint32_t dacr)
|
||||
{
|
||||
__MCR(15, 0, dacr, 3, 0, 0);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE uint32_t __get_DFSR(void)
|
||||
{
|
||||
return __MRC(15, 0, 5, 0, 0);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE void __set_DFSR(uint32_t dfsr)
|
||||
{
|
||||
__MCR(15, 0, dfsr, 5, 0, 0);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE uint32_t __get_IFSR(void)
|
||||
{
|
||||
return __MRC(15, 0, 5, 0, 1);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE void __set_IFSR(uint32_t ifsr)
|
||||
{
|
||||
__MCR(15, 0, ifsr, 5, 0, 1);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE uint32_t __get_DFAR(void)
|
||||
{
|
||||
return __MRC(15, 0, 6, 0, 0);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE void __set_DFAR(uint32_t dfar)
|
||||
{
|
||||
__MCR(15, 0, dfar, 6, 0, 0);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE uint32_t __get_IFAR(void)
|
||||
{
|
||||
return __MRC(15, 0, 6, 0, 2);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE void __set_IFAR(uint32_t ifar)
|
||||
{
|
||||
__MCR(15, 0, ifar, 6, 0, 2);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE uint32_t __get_VBAR(void)
|
||||
{
|
||||
return __MRC(15, 0, 12, 0, 0);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE void __set_VBAR(uint32_t vbar)
|
||||
{
|
||||
__MCR(15, 0, vbar, 12, 0, 0);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE uint32_t __get_ISR(void)
|
||||
{
|
||||
return __MRC(15, 0, 12, 1, 0);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE void __set_ISR(uint32_t isr)
|
||||
{
|
||||
__MCR(15, 0, isr, 12, 1, 0);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE uint32_t __get_CONTEXTIDR(void)
|
||||
{
|
||||
return __MRC(15, 0, 13, 0, 1);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE void __set_CONTEXTIDR(uint32_t contextidr)
|
||||
{
|
||||
__MCR(15, 0, contextidr, 13, 0, 1);
|
||||
}
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE uint32_t __get_CBAR(void)
|
||||
{
|
||||
return __MRC(15, 4, 15, 0, 0);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* GIC相关内容
|
||||
*有关GIC的内容,参考:ARM Generic Interrupt Controller(ARM GIC控制器)V2.0.pdf
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* GIC寄存器描述结构体,
|
||||
* GIC分为分发器端和CPU接口端
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t RESERVED0[1024];
|
||||
__IOM uint32_t D_CTLR; /*!< Offset: 0x1000 (R/W) Distributor Control Register */
|
||||
__IM uint32_t D_TYPER; /*!< Offset: 0x1004 (R/ ) Interrupt Controller Type Register */
|
||||
__IM uint32_t D_IIDR; /*!< Offset: 0x1008 (R/ ) Distributor Implementer Identification Register */
|
||||
uint32_t RESERVED1[29];
|
||||
__IOM uint32_t D_IGROUPR[16]; /*!< Offset: 0x1080 - 0x0BC (R/W) Interrupt Group Registers */
|
||||
uint32_t RESERVED2[16];
|
||||
__IOM uint32_t D_ISENABLER[16]; /*!< Offset: 0x1100 - 0x13C (R/W) Interrupt Set-Enable Registers */
|
||||
uint32_t RESERVED3[16];
|
||||
__IOM uint32_t D_ICENABLER[16]; /*!< Offset: 0x1180 - 0x1BC (R/W) Interrupt Clear-Enable Registers */
|
||||
uint32_t RESERVED4[16];
|
||||
__IOM uint32_t D_ISPENDR[16]; /*!< Offset: 0x1200 - 0x23C (R/W) Interrupt Set-Pending Registers */
|
||||
uint32_t RESERVED5[16];
|
||||
__IOM uint32_t D_ICPENDR[16]; /*!< Offset: 0x1280 - 0x2BC (R/W) Interrupt Clear-Pending Registers */
|
||||
uint32_t RESERVED6[16];
|
||||
__IOM uint32_t D_ISACTIVER[16]; /*!< Offset: 0x1300 - 0x33C (R/W) Interrupt Set-Active Registers */
|
||||
uint32_t RESERVED7[16];
|
||||
__IOM uint32_t D_ICACTIVER[16]; /*!< Offset: 0x1380 - 0x3BC (R/W) Interrupt Clear-Active Registers */
|
||||
uint32_t RESERVED8[16];
|
||||
__IOM uint8_t D_IPRIORITYR[512]; /*!< Offset: 0x1400 - 0x5FC (R/W) Interrupt Priority Registers */
|
||||
uint32_t RESERVED9[128];
|
||||
__IOM uint8_t D_ITARGETSR[512]; /*!< Offset: 0x1800 - 0x9FC (R/W) Interrupt Targets Registers */
|
||||
uint32_t RESERVED10[128];
|
||||
__IOM uint32_t D_ICFGR[32]; /*!< Offset: 0x1C00 - 0xC7C (R/W) Interrupt configuration registers */
|
||||
uint32_t RESERVED11[32];
|
||||
__IM uint32_t D_PPISR; /*!< Offset: 0x1D00 (R/ ) Private Peripheral Interrupt Status Register */
|
||||
__IM uint32_t D_SPISR[15]; /*!< Offset: 0x1D04 - 0xD3C (R/ ) Shared Peripheral Interrupt Status Registers */
|
||||
uint32_t RESERVED12[112];
|
||||
__OM uint32_t D_SGIR; /*!< Offset: 0x1F00 ( /W) Software Generated Interrupt Register */
|
||||
uint32_t RESERVED13[3];
|
||||
__IOM uint8_t D_CPENDSGIR[16]; /*!< Offset: 0x1F10 - 0xF1C (R/W) SGI Clear-Pending Registers */
|
||||
__IOM uint8_t D_SPENDSGIR[16]; /*!< Offset: 0x1F20 - 0xF2C (R/W) SGI Set-Pending Registers */
|
||||
uint32_t RESERVED14[40];
|
||||
__IM uint32_t D_PIDR4; /*!< Offset: 0x1FD0 (R/ ) Peripheral ID4 Register */
|
||||
__IM uint32_t D_PIDR5; /*!< Offset: 0x1FD4 (R/ ) Peripheral ID5 Register */
|
||||
__IM uint32_t D_PIDR6; /*!< Offset: 0x1FD8 (R/ ) Peripheral ID6 Register */
|
||||
__IM uint32_t D_PIDR7; /*!< Offset: 0x1FDC (R/ ) Peripheral ID7 Register */
|
||||
__IM uint32_t D_PIDR0; /*!< Offset: 0x1FE0 (R/ ) Peripheral ID0 Register */
|
||||
__IM uint32_t D_PIDR1; /*!< Offset: 0x1FE4 (R/ ) Peripheral ID1 Register */
|
||||
__IM uint32_t D_PIDR2; /*!< Offset: 0x1FE8 (R/ ) Peripheral ID2 Register */
|
||||
__IM uint32_t D_PIDR3; /*!< Offset: 0x1FEC (R/ ) Peripheral ID3 Register */
|
||||
__IM uint32_t D_CIDR0; /*!< Offset: 0x1FF0 (R/ ) Component ID0 Register */
|
||||
__IM uint32_t D_CIDR1; /*!< Offset: 0x1FF4 (R/ ) Component ID1 Register */
|
||||
__IM uint32_t D_CIDR2; /*!< Offset: 0x1FF8 (R/ ) Component ID2 Register */
|
||||
__IM uint32_t D_CIDR3; /*!< Offset: 0x1FFC (R/ ) Component ID3 Register */
|
||||
|
||||
__IOM uint32_t C_CTLR; /*!< Offset: 0x2000 (R/W) CPU Interface Control Register */
|
||||
__IOM uint32_t C_PMR; /*!< Offset: 0x2004 (R/W) Interrupt Priority Mask Register */
|
||||
__IOM uint32_t C_BPR; /*!< Offset: 0x2008 (R/W) Binary Point Register */
|
||||
__IM uint32_t C_IAR; /*!< Offset: 0x200C (R/ ) Interrupt Acknowledge Register */
|
||||
__OM uint32_t C_EOIR; /*!< Offset: 0x2010 ( /W) End Of Interrupt Register */
|
||||
__IM uint32_t C_RPR; /*!< Offset: 0x2014 (R/ ) Running Priority Register */
|
||||
__IM uint32_t C_HPPIR; /*!< Offset: 0x2018 (R/ ) Highest Priority Pending Interrupt Register */
|
||||
__IOM uint32_t C_ABPR; /*!< Offset: 0x201C (R/W) Aliased Binary Point Register */
|
||||
__IM uint32_t C_AIAR; /*!< Offset: 0x2020 (R/ ) Aliased Interrupt Acknowledge Register */
|
||||
__OM uint32_t C_AEOIR; /*!< Offset: 0x2024 ( /W) Aliased End Of Interrupt Register */
|
||||
__IM uint32_t C_AHPPIR; /*!< Offset: 0x2028 (R/ ) Aliased Highest Priority Pending Interrupt Register */
|
||||
uint32_t RESERVED15[41];
|
||||
__IOM uint32_t C_APR0; /*!< Offset: 0x20D0 (R/W) Active Priority Register */
|
||||
uint32_t RESERVED16[3];
|
||||
__IOM uint32_t C_NSAPR0; /*!< Offset: 0x20E0 (R/W) Non-secure Active Priority Register */
|
||||
uint32_t RESERVED17[6];
|
||||
__IM uint32_t C_IIDR; /*!< Offset: 0x20FC (R/ ) CPU Interface Identification Register */
|
||||
uint32_t RESERVED18[960];
|
||||
__OM uint32_t C_DIR; /*!< Offset: 0x3000 ( /W) Deactivate Interrupt Register */
|
||||
} GIC_Type;
|
||||
|
||||
|
||||
/*
|
||||
* GIC初始化
|
||||
* 为了简单使用GIC的group0
|
||||
*/
|
||||
FORCEDINLINE __STATIC_INLINE void GIC_Init(void)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t irqRegs;
|
||||
GIC_Type *gic = (GIC_Type *)(__get_CBAR() & 0xFFFF0000UL);
|
||||
|
||||
irqRegs = (gic->D_TYPER & 0x1FUL) + 1;
|
||||
|
||||
/* On POR, all SPI is in group 0, level-sensitive and using 1-N model */
|
||||
|
||||
/* Disable all PPI, SGI and SPI */
|
||||
for (i = 0; i < irqRegs; i++)
|
||||
gic->D_ICENABLER[i] = 0xFFFFFFFFUL;
|
||||
|
||||
/* Make all interrupts have higher priority */
|
||||
gic->C_PMR = (0xFFUL << (8 - __GIC_PRIO_BITS)) & 0xFFUL;
|
||||
|
||||
/* No subpriority, all priority level allows preemption */
|
||||
gic->C_BPR = 7 - __GIC_PRIO_BITS;
|
||||
|
||||
/* Enable group0 distribution */
|
||||
gic->D_CTLR = 1UL;
|
||||
|
||||
/* Enable group0 signaling */
|
||||
gic->C_CTLR = 1UL;
|
||||
}
|
||||
|
||||
/*
|
||||
* 使能指定的中断
|
||||
*/
|
||||
FORCEDINLINE __STATIC_INLINE void GIC_EnableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
GIC_Type *gic = (GIC_Type *)(__get_CBAR() & 0xFFFF0000UL);
|
||||
gic->D_ISENABLER[((uint32_t)(int32_t)IRQn) >> 5] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
|
||||
}
|
||||
|
||||
/*
|
||||
* 关闭指定的中断
|
||||
*/
|
||||
|
||||
FORCEDINLINE __STATIC_INLINE void GIC_DisableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
GIC_Type *gic = (GIC_Type *)(__get_CBAR() & 0xFFFF0000UL);
|
||||
gic->D_ICENABLER[((uint32_t)(int32_t)IRQn) >> 5] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
|
||||
}
|
||||
|
||||
/*
|
||||
* 返回中断号
|
||||
*/
|
||||
FORCEDINLINE __STATIC_INLINE uint32_t GIC_AcknowledgeIRQ(void)
|
||||
{
|
||||
GIC_Type *gic = (GIC_Type *)(__get_CBAR() & 0xFFFF0000UL);
|
||||
return gic->C_IAR & 0x1FFFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* 向EOIR写入发送中断的中断号来释放中断
|
||||
*/
|
||||
FORCEDINLINE __STATIC_INLINE void GIC_DeactivateIRQ(uint32_t value)
|
||||
{
|
||||
GIC_Type *gic = (GIC_Type *)(__get_CBAR() & 0xFFFF0000UL);
|
||||
gic->C_EOIR = value;
|
||||
}
|
||||
|
||||
/*
|
||||
* 获取运行优先级
|
||||
*/
|
||||
FORCEDINLINE __STATIC_INLINE uint32_t GIC_GetRunningPriority(void)
|
||||
{
|
||||
GIC_Type *gic = (GIC_Type *)(__get_CBAR() & 0xFFFF0000UL);
|
||||
return gic->C_RPR & 0xFFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* 设置组优先级
|
||||
*/
|
||||
FORCEDINLINE __STATIC_INLINE void GIC_SetPriorityGrouping(uint32_t PriorityGroup)
|
||||
{
|
||||
GIC_Type *gic = (GIC_Type *)(__get_CBAR() & 0xFFFF0000UL);
|
||||
gic->C_BPR = PriorityGroup & 0x7UL;
|
||||
}
|
||||
|
||||
/*
|
||||
* 获取组优先级
|
||||
*/
|
||||
FORCEDINLINE __STATIC_INLINE uint32_t GIC_GetPriorityGrouping(void)
|
||||
{
|
||||
GIC_Type *gic = (GIC_Type *)(__get_CBAR() & 0xFFFF0000UL);
|
||||
|
||||
return gic->C_BPR & 0x7UL;
|
||||
}
|
||||
|
||||
/*
|
||||
* 设置优先级
|
||||
*/
|
||||
FORCEDINLINE __STATIC_INLINE void GIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
|
||||
{
|
||||
GIC_Type *gic = (GIC_Type *)(__get_CBAR() & 0xFFFF0000UL);
|
||||
gic->D_IPRIORITYR[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8UL - __GIC_PRIO_BITS)) & (uint32_t)0xFFUL);
|
||||
}
|
||||
|
||||
/*
|
||||
* 获取优先级
|
||||
*/
|
||||
FORCEDINLINE __STATIC_INLINE uint32_t GIC_GetPriority(IRQn_Type IRQn)
|
||||
{
|
||||
GIC_Type *gic = (GIC_Type *)(__get_CBAR() & 0xFFFF0000UL);
|
||||
return(((uint32_t)gic->D_IPRIORITYR[((uint32_t)(int32_t)IRQn)] >> (8UL - __GIC_PRIO_BITS)));
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,28 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _IMX6UL_H_
|
||||
#define _IMX6UL_H_
|
||||
|
||||
#include "MCIMX6Y2.h"
|
||||
#include "core_ca7.h"
|
||||
|
||||
#include "clock.h"
|
||||
#include "systick.h"
|
||||
|
||||
#endif /* _IMX6UL_H_ */
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef _SYSTICK_H_
|
||||
#define _SYSTICK_H_
|
||||
|
||||
void systick_init(k_tick_t tick_per_second);
|
||||
|
||||
#endif /* _SYSTICK_H_ */
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#include "tos_k.h"
|
||||
#include "imx6ul.h"
|
||||
|
||||
static void epit1_init(unsigned int frac, unsigned int value)
|
||||
{
|
||||
if (frac > 0XFFF) {
|
||||
frac = 0XFFF;
|
||||
}
|
||||
|
||||
EPIT1->CR = 0;
|
||||
|
||||
EPIT1->CR = (1 << 24 | frac << 4 | 1 << 3 | 1 << 2 | 1 << 1);
|
||||
|
||||
EPIT1->LR = value;
|
||||
EPIT1->CMPR = 0;
|
||||
|
||||
GIC_EnableIRQ(EPIT1_IRQn);
|
||||
|
||||
EPIT1->CR |= 1 << 0;
|
||||
}
|
||||
|
||||
void systick_handler(void *arg)
|
||||
{
|
||||
if (EPIT1->SR & (1 << 0)) {
|
||||
tos_tick_handler();
|
||||
}
|
||||
|
||||
EPIT1->SR |= 1 << 0;
|
||||
}
|
||||
|
||||
void systick_init(k_tick_t tick_per_second)
|
||||
{
|
||||
epit1_init(0, 66000000 / tick_per_second);
|
||||
|
||||
tos_interrupt_handler_register(EPIT1_IRQn, (int_handler_t)systick_handler, NULL);
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/* Fuchsia's code is nice here, so I learn from it(fine, almost copy). thanks */
|
||||
|
||||
#include "exceptions.h"
|
||||
|
||||
.global arm_undefined
|
||||
.global arm_syscall
|
||||
.global arm_prefetch_abort
|
||||
.global arm_data_abort
|
||||
.global arm_reserved
|
||||
.global arm_irq
|
||||
.global arm_fiq
|
||||
|
||||
.extern tos_knl_irq_enter
|
||||
.extern tos_knl_irq_leave
|
||||
.extern interrupt_irq
|
||||
|
||||
.syntax unified
|
||||
.text
|
||||
|
||||
.type arm_undefined, %function
|
||||
arm_undefined:
|
||||
save
|
||||
/* r0 now holds pointer to iframe */
|
||||
|
||||
bl arm_undefined_handler
|
||||
|
||||
restore
|
||||
|
||||
|
||||
.type arm_syscall, %function
|
||||
arm_syscall:
|
||||
b .
|
||||
|
||||
|
||||
.type arm_prefetch_abort, %function
|
||||
arm_prefetch_abort:
|
||||
saveall_offset #4
|
||||
/* r0 now holds pointer to iframe */
|
||||
|
||||
bl arm_prefetch_abort_handler
|
||||
|
||||
restoreall
|
||||
|
||||
|
||||
.type arm_data_abort, %function
|
||||
arm_data_abort:
|
||||
saveall_offset #8
|
||||
/* r0 now holds pointer to iframe */
|
||||
|
||||
bl arm_data_abort_handler
|
||||
|
||||
restoreall
|
||||
|
||||
|
||||
.type arm_reserved, %function
|
||||
arm_reserved:
|
||||
b .
|
||||
|
||||
|
||||
.type arm_irq, %function
|
||||
arm_irq:
|
||||
saveall_offset #4
|
||||
|
||||
/* r0 now holds pointer to iframe */
|
||||
bl tos_knl_irq_enter
|
||||
|
||||
/* call into higher level code */
|
||||
bl interrupt_irq
|
||||
|
||||
bl tos_knl_irq_leave
|
||||
|
||||
restoreall
|
||||
|
||||
|
||||
.type arm_fiq, %function
|
||||
arm_fiq:
|
||||
b .
|
||||
|
||||
.end
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
/* macros to align and unalign the stack on 8 byte boundary for ABI compliance */
|
||||
.macro stack_align, tempreg
|
||||
/* make sure the stack is aligned */
|
||||
mov \tempreg, sp
|
||||
tst sp, #4
|
||||
subeq sp, #4
|
||||
push { \tempreg }
|
||||
|
||||
/* tempreg holds the original stack */
|
||||
.endm
|
||||
|
||||
.macro stack_restore, tempreg
|
||||
/* restore the potentially unaligned stack */
|
||||
pop { \tempreg }
|
||||
mov sp, \tempreg
|
||||
.endm
|
||||
|
||||
/* save and disable the vfp unit */
|
||||
.macro vfp_save, temp1
|
||||
/* save old fpexc */
|
||||
vmrs \temp1, fpexc
|
||||
|
||||
push { \temp1 }
|
||||
|
||||
/* hard disable the vfp unit */
|
||||
bic \temp1, #(1<<30)
|
||||
vmsr fpexc, \temp1
|
||||
.endm
|
||||
|
||||
/* restore the vfp enable/disable state */
|
||||
.macro vfp_restore, temp1
|
||||
/* restore fpexc */
|
||||
pop { \temp1 }
|
||||
|
||||
vmsr fpexc, \temp1
|
||||
.endm
|
||||
|
||||
/* Save callee trashed registers.
|
||||
* At exit r0 contains a pointer to the register frame.
|
||||
*/
|
||||
.macro save
|
||||
/* save spsr and r14 onto the svc stack */
|
||||
srsdb #0x13!
|
||||
|
||||
/* switch to svc mode, interrupts disabled */
|
||||
cpsid i, #0x13
|
||||
|
||||
/* save callee trashed regs and lr */
|
||||
push { r0-r3, r12, lr }
|
||||
|
||||
#if 0
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
/* save and disable the vfp unit */
|
||||
vfp_save r0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* make sure the stack is 8 byte aligned */
|
||||
stack_align r0
|
||||
|
||||
/* r0 now holds the pointer to the original iframe (before alignment) */
|
||||
.endm
|
||||
|
||||
.macro save_offset, offset
|
||||
sub lr, \offset
|
||||
save
|
||||
.endm
|
||||
|
||||
.macro restore
|
||||
/* undo the stack alignment we did before */
|
||||
stack_restore r0
|
||||
|
||||
#if 0
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
/* restore the old state of the vfp unit */
|
||||
vfp_restore r0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
pop { r0-r3, r12, lr }
|
||||
|
||||
/* return to whence we came from */
|
||||
rfeia sp!
|
||||
.endm
|
||||
|
||||
/* Save all registers.
|
||||
* At exit r0 contains a pointer to the register frame.
|
||||
*/
|
||||
.macro saveall
|
||||
/* save spsr and r14 onto the svc stack */
|
||||
srsdb #0x13!
|
||||
|
||||
/* switch to svc mode, interrupts disabled */
|
||||
cpsid i,#0x13
|
||||
|
||||
/* save all regs */
|
||||
push { r0-r12, lr }
|
||||
|
||||
#if 0
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
/* save and disable the vfp unit */
|
||||
vfp_save r0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* make sure the stack is 8 byte aligned */
|
||||
stack_align r0
|
||||
|
||||
/* r0 now holds the pointer to the original iframe (before alignment) */
|
||||
.endm
|
||||
|
||||
.macro saveall_offset, offset
|
||||
sub lr, \offset
|
||||
saveall
|
||||
.endm
|
||||
|
||||
.macro restoreall
|
||||
/* undo the stack alignment we did before */
|
||||
stack_restore r0
|
||||
|
||||
#if 0
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
/* restore the old state of the vfp unit */
|
||||
vfp_restore r0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
pop { r0-r12, r14 }
|
||||
|
||||
/* return to whence we came from */
|
||||
rfeia sp!
|
||||
.endm
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _PORT_H_
|
||||
#define _PORT_H_
|
||||
|
||||
__PORT__ void port_int_disable(void);
|
||||
|
||||
__PORT__ void port_int_enable(void);
|
||||
|
||||
__PORT__ cpu_cpsr_t port_cpsr_save(void);
|
||||
|
||||
__PORT__ void port_cpsr_restore(cpu_cpsr_t cpsr);
|
||||
|
||||
__PORT__ void port_cpu_reset(void);
|
||||
|
||||
__PORT__ void port_sched_start(void) __NO_RETURN__;
|
||||
|
||||
__PORT__ void port_context_switch(void);
|
||||
|
||||
__PORT__ void port_irq_context_switch(void);
|
||||
|
||||
__PORT__ void port_systick_config(uint32_t cycle_per_tick);
|
||||
|
||||
__PORT__ void port_systick_priority_set(uint32_t prio);
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN > 0u
|
||||
|
||||
__PORT__ void port_systick_resume(void);
|
||||
|
||||
__PORT__ void port_systick_suspend(void);
|
||||
|
||||
__PORT__ void port_systick_reload(uint32_t cycle_per_tick);
|
||||
|
||||
__PORT__ void port_systick_pending_reset(void);
|
||||
|
||||
__PORT__ k_time_t port_systick_max_delay_millisecond(void);
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__PORT__ void port_sleep_mode_enter(void);
|
||||
|
||||
__PORT__ void port_stop_mode_enter(void);
|
||||
|
||||
__PORT__ void port_standby_mode_enter(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
__PORT__ void HardFault_Handler(void);
|
||||
|
||||
__PORT__ void port_fault_diagnosis(void);
|
||||
#endif
|
||||
|
||||
#endif /* _PORT_H_ */
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos_k.h"
|
||||
|
||||
__PORT__ void port_cpu_reset(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_config(uint32_t cycle_per_tick)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_priority_set(uint32_t prio)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN > 0u
|
||||
|
||||
__PORT__ k_time_t port_systick_max_delay_millisecond(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_resume(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_suspend(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_reload(uint32_t cycle_per_tick)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_pending_reset(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__PORT__ void port_sleep_mode_enter(void)
|
||||
{
|
||||
#if 0
|
||||
#if 1
|
||||
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
|
||||
#else
|
||||
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
__PORT__ void port_stop_mode_enter(void)
|
||||
{
|
||||
#if 0
|
||||
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
|
||||
#endif
|
||||
}
|
||||
|
||||
__PORT__ void port_standby_mode_enter(void)
|
||||
{
|
||||
#if 0
|
||||
HAL_PWR_EnterSTANDBYMode();
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
__PORT__ void port_fault_diagnosis(void)
|
||||
{
|
||||
// k_fault_log_writer("fault diagnosis is not supported in CORTEX a7\n");
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*------------------ RealView Compiler -----------------*/
|
||||
/* V5 */
|
||||
#if defined(__CC_ARM)
|
||||
|
||||
__PORT__ __ASM__ void HardFault_Handler(void)
|
||||
{
|
||||
IMPORT fault_backtrace
|
||||
|
||||
MOV r0, lr
|
||||
TST lr, #0x04
|
||||
ITE EQ
|
||||
MRSEQ r1, MSP
|
||||
MRSNE r1, PSP
|
||||
BL fault_backtrace
|
||||
}
|
||||
|
||||
/*------------------ ARM Compiler V6 -------------------*/
|
||||
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
|
||||
__PORT__ void __NAKED__ HardFault_Handler(void)
|
||||
{
|
||||
__ASM__ __VOLATILE__ (
|
||||
"MOV r0, lr\n\t"
|
||||
"TST lr, #0x04\n\t"
|
||||
"ITE EQ\n\t"
|
||||
"MRSEQ r1, MSP\n\t"
|
||||
"MRSNE r1, PSP\n\t"
|
||||
"BL fault_backtrace\n\t"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* ARMCC VERSION */
|
||||
#endif
|
||||
|
||||
#endif /* TOS_CFG_FAULT_BACKTRACE_EN */
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _PORT_CONFIG_H_
|
||||
#define _PORT_CONFIG_H_
|
||||
|
||||
#define TOS_CFG_CPU_ADDR_SIZE CPU_WORD_SIZE_32
|
||||
#define TOS_CFG_CPU_DATA_SIZE CPU_WORD_SIZE_32
|
||||
#define TOS_CFG_CPU_STK_GROWTH CPU_STK_GROWTH_DESCENDING
|
||||
// #define TOS_CFG_CPU_HRTIMER_SIZE CPU_WORD_SIZE_32
|
||||
#define TOS_CFG_CPU_HRTIMER_EN 0u
|
||||
#define TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT 0u
|
||||
#define TOS_CFG_CPU_BYTE_ORDER CPU_BYTE_ORDER_LITTLE_ENDIAN
|
||||
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
#define TOS_CFG_CPU_ARM_FPU_EN 1u
|
||||
#else
|
||||
#define TOS_CFG_CPU_ARM_FPU_EN 0u
|
||||
#endif
|
||||
|
||||
#endif /* _PORT_CONFIG_H_ */
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
.global port_int_disable
|
||||
.global port_int_enable
|
||||
.global port_cpsr_save
|
||||
.global port_cpsr_restore
|
||||
.global port_sched_start
|
||||
.global port_context_switch
|
||||
.global port_irq_context_switch
|
||||
|
||||
.extern k_curr_task
|
||||
.extern k_next_task
|
||||
|
||||
.syntax unified
|
||||
.align 2
|
||||
.text
|
||||
|
||||
.type port_int_disable, %function
|
||||
port_int_disable:
|
||||
CPSID I
|
||||
|
||||
.type port_int_enable, %function
|
||||
port_int_enable:
|
||||
CPSIE I
|
||||
|
||||
.type port_cpsr_save, %function
|
||||
port_cpsr_save:
|
||||
MRS R0, CPSR
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
.type port_cpsr_restore, %function
|
||||
port_cpsr_restore:
|
||||
MSR CPSR, R0
|
||||
BX LR
|
||||
|
||||
.type port_sched_start, %function
|
||||
port_sched_start:
|
||||
B .L__context_restore
|
||||
|
||||
.type port_context_switch, %function
|
||||
port_context_switch:
|
||||
.L__context_save:
|
||||
STR R0, [SP, #-0xC] /* backup R0 */
|
||||
|
||||
MRS R0, CPSR
|
||||
TST LR, #0x01
|
||||
ORRNE R0, R0, 0x20 /* set thumb bit*/
|
||||
|
||||
STMFD SP!, { R0 } /* save CPSR */
|
||||
STMFD SP!, { LR } /* save PC */
|
||||
|
||||
LDR R0, [SP, #-0x4] /* restore R0 */
|
||||
STMFD SP!, { R0 - R12, LR }
|
||||
|
||||
/* k_curr_task->sp = SP */
|
||||
LDR R0, =k_curr_task
|
||||
LDR R0, [R0]
|
||||
STR SP, [R0]
|
||||
|
||||
.L__context_restore:
|
||||
/* k_curr_task = k_next_task */
|
||||
LDR R0, =k_next_task
|
||||
LDR R0, [R0]
|
||||
LDR R1, =k_curr_task
|
||||
STR R0, [R1]
|
||||
|
||||
/* SP = k_next_task->sp */
|
||||
LDR SP, [R0]
|
||||
|
||||
LDMFD SP!, { R0 - R12, LR }
|
||||
RFEIA SP!
|
||||
|
||||
.type port_irq_context_switch, %function
|
||||
port_irq_context_switch:
|
||||
/* we already store the k_curr_task's context onto its stack by arm_irq(see saveall_offset) */
|
||||
|
||||
/* ATTENTION:
|
||||
our kernel always runs in SVC mode even in user task,
|
||||
if one day we make the user task run in USR mode(although I cannot see any meaning to do this in RTOS),
|
||||
we must deal with more logic
|
||||
*/
|
||||
B .L__context_restore /* magnificent */
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
.equ MODE_USR, 0x10
|
||||
.equ MODE_FIQ, 0x11
|
||||
.equ MODE_IRQ, 0x12
|
||||
.equ MODE_SVC, 0x13
|
||||
.equ MODE_ABT, 0x17
|
||||
.equ MODE_UND, 0x1B
|
||||
.equ MODE_SYS, 0x1F
|
||||
|
||||
.equ BIT_I, 0x80 @ when I bit is set, IRQ is disabled
|
||||
.equ BIT_F, 0x40 @ when F bit is set, FIQ is disabled
|
||||
|
||||
.equ STACK_SIZE_USR, 0x00000100
|
||||
.equ STACK_SIZE_FIQ, 0x00000100
|
||||
.equ STACK_SIZE_IRQ, 0x00001000
|
||||
.equ STACK_SIZE_ABT, 0x00000100
|
||||
.equ STACK_SIZE_UND, 0x00000100
|
||||
.equ STACK_SIZE_SYS, 0x00000800
|
||||
.equ STACK_SIZE_SVC, 0x00001000
|
||||
|
||||
.syntax unified
|
||||
|
||||
.section ".text.vector", "ax"
|
||||
.code 32
|
||||
.align 0
|
||||
.global _start
|
||||
_start:
|
||||
_vector:
|
||||
ldr pc, vector_reset
|
||||
ldr pc, vector_undefined
|
||||
ldr pc, vector_swi
|
||||
ldr pc, vector_prefetch_abort
|
||||
ldr pc, vector_data_abort
|
||||
ldr pc, vector_reserved
|
||||
ldr pc, vector_irq
|
||||
ldr pc, vector_fiq
|
||||
|
||||
.align 3
|
||||
|
||||
vector_reset:
|
||||
.word arm_reset
|
||||
|
||||
vector_undefined:
|
||||
.word arm_undefined
|
||||
|
||||
vector_swi:
|
||||
.word arm_syscall
|
||||
|
||||
vector_prefetch_abort:
|
||||
.word arm_prefetch_abort
|
||||
|
||||
vector_data_abort:
|
||||
.word arm_data_abort
|
||||
|
||||
vector_reserved:
|
||||
.word arm_reserved
|
||||
|
||||
vector_irq:
|
||||
.word arm_irq
|
||||
|
||||
vector_fiq:
|
||||
.word arm_fiq
|
||||
|
||||
.section ".text", "ax"
|
||||
.global arm_reset
|
||||
arm_reset:
|
||||
.L__cache_disable:
|
||||
mrc p15, 0, r12, c1, c0, 0 /* read SCTLR */
|
||||
bic r12, #(1 << 12) /* i-cache disable */
|
||||
bic r12, #(1 << 2 | 1 << 0) /* d-cache, mmu disable */
|
||||
mcr p15, 0, r12, c1, c0, 0 /* write SCTLR */
|
||||
|
||||
/* set up the stack */
|
||||
.L__stack_setup:
|
||||
cpsid i, #MODE_IRQ /* irq */
|
||||
ldr sp, =__irq_stack_limit
|
||||
|
||||
cpsid i, #MODE_FIQ /* fiq */
|
||||
ldr sp, =__fiq_stack_limit
|
||||
|
||||
cpsid i, #MODE_ABT /* abort */
|
||||
ldr sp, =__abt_stack_limit
|
||||
|
||||
cpsid i, #MODE_UND /* undefined */
|
||||
ldr sp, =__und_stack_limit
|
||||
|
||||
cpsid i, #MODE_SYS /* system */
|
||||
ldr sp, =__sys_stack_limit
|
||||
|
||||
cpsid i, #MODE_SVC /* supervisor */
|
||||
ldr sp, =__svc_stack_limit
|
||||
|
||||
/* init vector table */
|
||||
.L__vector_setup:
|
||||
dsb
|
||||
isb
|
||||
ldr r0, =_vector
|
||||
mcr p15, 0, r0, c12, c0, #0 /* write VBAR */
|
||||
dsb
|
||||
isb
|
||||
|
||||
/* clear bss */
|
||||
.L__bss_clear:
|
||||
ldr r0, =__bss_start__
|
||||
ldr r1, =__bss_end__
|
||||
mov r2, #0
|
||||
|
||||
.L__bss_loop:
|
||||
cmp r0, r1
|
||||
strlt r2, [r0], #4
|
||||
blt .L__bss_loop
|
||||
|
||||
bl main
|
||||
b .
|
||||
|
||||
.section ".bss.prebss.exc_stk", "wa"
|
||||
.bss
|
||||
.align 2
|
||||
|
||||
__usr_stack_base:
|
||||
.space STACK_SIZE_USR
|
||||
__usr_stack_limit:
|
||||
|
||||
__fiq_stack_base:
|
||||
.space STACK_SIZE_FIQ
|
||||
__fiq_stack_limit:
|
||||
|
||||
__irq_stack_base:
|
||||
.space STACK_SIZE_IRQ
|
||||
__irq_stack_limit:
|
||||
|
||||
__abt_stack_base:
|
||||
.space STACK_SIZE_ABT
|
||||
__abt_stack_limit:
|
||||
|
||||
__und_stack_base:
|
||||
.space STACK_SIZE_UND
|
||||
__und_stack_limit:
|
||||
|
||||
__sys_stack_base:
|
||||
.space STACK_SIZE_SYS
|
||||
__sys_stack_limit:
|
||||
|
||||
__svc_stack_base:
|
||||
.space STACK_SIZE_SVC
|
||||
__svc_stack_limit:
|
||||
|
||||
.size __usr_stack_base, . - __usr_stack_base
|
||||
|
||||
.end
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
#include "chip/chip.h"
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = KERNEL_BASE;
|
||||
|
||||
_start = .;
|
||||
|
||||
.text : AT(KERNEL_BASE) {
|
||||
__text_start = .;
|
||||
|
||||
KEEP(*(.text.vector))
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
|
||||
KEEP(*(.init))
|
||||
KEEP(*(.fini))
|
||||
}
|
||||
|
||||
.ARM.extab : ALIGN(4) {
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
}
|
||||
|
||||
/* .ARM.exidx is sorted, so has to go in its own output section. */
|
||||
__exidx_start = .;
|
||||
.ARM.exidx : ALIGN(4) {
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
}
|
||||
__exidx_end = .;
|
||||
|
||||
.dummy_post_text : {
|
||||
__text_end = .;
|
||||
}
|
||||
|
||||
.rodata : ALIGN(4) {
|
||||
__rodata_start = .;
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
}
|
||||
|
||||
.dummy_post_rodata : {
|
||||
__rodata_end = .;
|
||||
}
|
||||
|
||||
.data : ALIGN(4) {
|
||||
__data_start = .;
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
}
|
||||
|
||||
.ctors : ALIGN(4) {
|
||||
__ctor_list = .;
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.ctors .init_array*))
|
||||
__ctor_end = .;
|
||||
}
|
||||
|
||||
.dtors : ALIGN(4) {
|
||||
__dtor_list = .;
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
KEEP (*(.dtors .fini_array*))
|
||||
__dtor_end = .;
|
||||
}
|
||||
|
||||
.dummy_post_rodata : {
|
||||
__data_end = .;
|
||||
}
|
||||
|
||||
.bss : ALIGN(4) {
|
||||
KEEP(*(.bss.prebss.*))
|
||||
. = ALIGN(4);
|
||||
__bss_start__ = .;
|
||||
*(.bss .bss.*)
|
||||
*(COMMON)
|
||||
|
||||
. = ALIGN(4);
|
||||
__bss_end__ = .;
|
||||
}
|
||||
|
||||
_end = .;
|
||||
|
||||
/* Strip unnecessary stuff */
|
||||
/DISCARD/ : { *(.comment .note) }
|
||||
}
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_CPU_H_
|
||||
#define _TOS_CPU_H_
|
||||
|
||||
typedef struct cpu_context_st {
|
||||
cpu_data_t _R4;
|
||||
cpu_data_t _R5;
|
||||
cpu_data_t _R6;
|
||||
cpu_data_t _R7;
|
||||
cpu_data_t _R8;
|
||||
cpu_data_t _R9;
|
||||
cpu_data_t _R10;
|
||||
cpu_data_t _R11;
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
cpu_data_t EXC_RETURN;
|
||||
#endif
|
||||
cpu_data_t _R0;
|
||||
cpu_data_t _R1;
|
||||
cpu_data_t _R2;
|
||||
cpu_data_t _R3;
|
||||
cpu_data_t _R12;
|
||||
cpu_data_t _R14;
|
||||
cpu_data_t _PC;
|
||||
cpu_data_t _xPSR;
|
||||
} cpu_context_t;
|
||||
|
||||
__API__ uint32_t tos_cpu_clz(uint32_t val);
|
||||
|
||||
__API__ void tos_cpu_int_disable(void);
|
||||
|
||||
__API__ void tos_cpu_int_enable(void);
|
||||
|
||||
__API__ cpu_cpsr_t tos_cpu_cpsr_save(void);
|
||||
|
||||
__API__ void tos_cpu_cpsr_restore(cpu_cpsr_t cpsr);
|
||||
|
||||
#if (TOS_CFG_CPU_HRTIMER_EN > 0u)
|
||||
|
||||
__API__ void tos_cpu_hrtimer_init(void);
|
||||
|
||||
__API__ cpu_hrtimer_t tos_cpu_hrtimer_read(void);
|
||||
|
||||
#endif
|
||||
|
||||
__KNL__ void cpu_init(void);
|
||||
|
||||
__KNL__ void cpu_reset(void);
|
||||
|
||||
__KNL__ void cpu_systick_init(k_cycle_t cycle_per_tick);
|
||||
|
||||
__KNL__ void cpu_sched_start(void);
|
||||
|
||||
__KNL__ void cpu_context_switch(void);
|
||||
|
||||
__KNL__ void cpu_irq_context_switch(void);
|
||||
|
||||
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
|
||||
|
||||
__KNL__ k_err_t cpu_task_stack_draught_depth(k_stack_t *stk_base, size_t stk_size, int *depth);
|
||||
|
||||
#endif
|
||||
|
||||
__KNL__ k_stack_t *cpu_task_stk_init(void *entry,
|
||||
void *arg,
|
||||
void *exit,
|
||||
k_stack_t *stk_base,
|
||||
size_t stk_size);
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN > 0u
|
||||
|
||||
__KNL__ void cpu_systick_resume(void);
|
||||
|
||||
__KNL__ void cpu_systick_suspend(void);
|
||||
|
||||
__KNL__ void cpu_systick_reload_reset(void);
|
||||
|
||||
__KNL__ void cpu_systick_pending_reset(void);
|
||||
|
||||
__KNL__ k_time_t cpu_systick_max_delay_millisecond(void);
|
||||
|
||||
__KNL__ void cpu_systick_expires_set(k_time_t millisecond);
|
||||
|
||||
__KNL__ void cpu_systick_reset(void);
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__KNL__ void cpu_sleep_mode_enter(void);
|
||||
|
||||
__KNL__ void cpu_stop_mode_enter(void);
|
||||
|
||||
__KNL__ void cpu_standby_mode_enter(void);
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
|
||||
__KNL__ void cpu_flush_fpu(void);
|
||||
|
||||
#endif /* TOS_CFG_CPU_ARM_FPU_EN */
|
||||
|
||||
__KNL__ void cpu_fault_diagnosis(void);
|
||||
|
||||
#endif
|
||||
|
||||
/* Allocates CPU status register word. */
|
||||
#define TOS_CPU_CPSR_ALLOC() cpu_cpsr_t cpu_cpsr = (cpu_cpsr_t)0u
|
||||
|
||||
/* Save CPU status word & disable interrupts.*/
|
||||
#define TOS_CPU_INT_DISABLE() \
|
||||
do { \
|
||||
cpu_cpsr = tos_cpu_cpsr_save(); \
|
||||
} while (0)
|
||||
|
||||
/* Restore CPU status word. */
|
||||
#define TOS_CPU_INT_ENABLE() \
|
||||
do { \
|
||||
tos_cpu_cpsr_restore(cpu_cpsr); \
|
||||
} while (0)
|
||||
|
||||
#endif /* _TOS_CPU_H_ */
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_CPU_DEF_H_
|
||||
#define _TOS_CPU_DEF_H_
|
||||
|
||||
#define CPU_WORD_SIZE_08 1
|
||||
#define CPU_WORD_SIZE_16 2
|
||||
#define CPU_WORD_SIZE_32 3
|
||||
#define CPU_WORD_SIZE_64 4
|
||||
|
||||
#define CPU_STK_GROWTH_ASCENDING 1
|
||||
#define CPU_STK_GROWTH_DESCENDING 2
|
||||
|
||||
#define CPU_BYTE_ORDER_LITTLE_ENDIAN 1
|
||||
#define CPU_BYTE_ORDER_BIG_ENDIAN 2
|
||||
|
||||
#endif /* _TOS_CPU_DEF_H_ */
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_CPU_TYPES_H_
|
||||
#define _TOS_CPU_TYPES_H_
|
||||
|
||||
/* CPU address type based on address bus size. */
|
||||
#if (TOS_CFG_CPU_ADDR_SIZE == CPU_WORD_SIZE_32)
|
||||
typedef uint32_t cpu_addr_t;
|
||||
#elif (TOS_CFG_CPU_ADDR_SIZE == CPU_WORD_SIZE_16)
|
||||
typedef uint16_t cpu_addr_t;
|
||||
#else
|
||||
typedef uint8_t cpu_addr_t;
|
||||
#endif
|
||||
|
||||
/* CPU data type based on data bus size. */
|
||||
#if (TOS_CFG_CPU_DATA_SIZE == CPU_WORD_SIZE_32)
|
||||
typedef uint32_t cpu_data_t;
|
||||
#elif (TOS_CFG_CPU_DATA_SIZE == CPU_WORD_SIZE_16)
|
||||
typedef uint16_t cpu_data_t;
|
||||
#else
|
||||
typedef uint8_t cpu_data_t;
|
||||
#endif
|
||||
|
||||
#if (TOS_CFG_CPU_HRTIMER_EN > 0)
|
||||
#if (TOS_CFG_CPU_HRTIMER_SIZE == CPU_WORD_SIZE_08)
|
||||
typedef uint8_t cpu_hrtimer_t;
|
||||
#elif (TOS_CFG_CPU_HRTIMER_SIZE == CPU_WORD_SIZE_16)
|
||||
typedef uint16_t cpu_hrtimer_t;
|
||||
#elif (TOS_CFG_CPU_HRTIMER_SIZE == CPU_WORD_SIZE_64)
|
||||
typedef uint64_t cpu_hrtimer_t;
|
||||
#else
|
||||
typedef uint32_t cpu_hrtimer_t;
|
||||
#endif
|
||||
#else
|
||||
typedef uint32_t cpu_hrtimer_t;
|
||||
#endif
|
||||
|
||||
typedef cpu_addr_t cpu_cpsr_t;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_FAULT_H_
|
||||
#define _TOS_FAULT_H_
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
|
||||
typedef int (*k_fault_log_writer_t)(const char *format, ...);
|
||||
|
||||
#define K_FAULT_STACK_DUMP_DEPTH 10u
|
||||
|
||||
#define K_FAULT_CALL_STACK_BACKTRACE_DEPTH 5u
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
typedef struct fault_fpu_frame_st {
|
||||
cpu_data_t s0;
|
||||
cpu_data_t s1;
|
||||
cpu_data_t s2;
|
||||
cpu_data_t s3;
|
||||
cpu_data_t s4;
|
||||
cpu_data_t s5;
|
||||
cpu_data_t s6;
|
||||
cpu_data_t s7;
|
||||
cpu_data_t s8;
|
||||
cpu_data_t s9;
|
||||
cpu_data_t s10;
|
||||
cpu_data_t s11;
|
||||
cpu_data_t s12;
|
||||
cpu_data_t s13;
|
||||
cpu_data_t s14;
|
||||
cpu_data_t s15;
|
||||
cpu_data_t fpscr;
|
||||
} fault_fpu_frame_t;
|
||||
#endif
|
||||
|
||||
typedef struct fault_cpu_frame_st {
|
||||
cpu_data_t r0;
|
||||
cpu_data_t r1;
|
||||
cpu_data_t r2;
|
||||
cpu_data_t r3;
|
||||
cpu_data_t r12;
|
||||
cpu_data_t lr;
|
||||
cpu_data_t pc;
|
||||
cpu_data_t spsr;
|
||||
} fault_cpu_frame_t;
|
||||
|
||||
typedef struct fault_exc_frame_st {
|
||||
fault_cpu_frame_t cpu_frame;
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
fault_fpu_frame_t fpu_frame;
|
||||
#endif
|
||||
} fault_exc_frame_t;
|
||||
|
||||
/**
|
||||
* information we need to do fault backtrace
|
||||
*/
|
||||
typedef struct fault_information_st {
|
||||
int is_thumb : 1; /**< whether it is thumb we use when we fall into fault? */
|
||||
int is_on_task : 1; /**< whether we are on a task when fall into fault? */
|
||||
int is_stk_ovrf : 1; /**< whether we get a stack overflow */
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
int is_ext_stk_frm : 1; /**< whether it is a extended stack frame?(whether the cpu has pushed fpu registers onto the stack) */
|
||||
#endif
|
||||
|
||||
cpu_addr_t pc; /**< just where fault happens */
|
||||
|
||||
cpu_addr_t sp_before_fault; /**< original sp just before the cpu push the fault exception frame */
|
||||
|
||||
/**
|
||||
* we need main_stack_start & main_stack_limit to do call stack backtrace
|
||||
* when we fall into fault during a task, we should do the call stack backtrace on the task's stack
|
||||
* but if not, which means we are in kernel, we should do the call stack backtrace on the main stack
|
||||
* in arm v7-m, this should be the MSP's start and limit
|
||||
* in arm v7-a, call stack backtrace is another story(much more elegant because we have FP).
|
||||
*/
|
||||
cpu_addr_t stack_start; /**< current sp start address we use. if on task, it'll be the task's stack, otherwise it'll be the msp */
|
||||
cpu_addr_t stack_limit; /**< current sp limit address */
|
||||
cpu_addr_t code_start; /**< current code start address */
|
||||
cpu_addr_t code_limit; /**< current code limit address */
|
||||
} fault_info_t;
|
||||
|
||||
#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
|
||||
|
||||
#define DEFAULT_CODE_SECTION_NAME ER_IROM1
|
||||
#define DEFAULT_CSTACK_SECTION_NAME STACK
|
||||
|
||||
#define SECTION_START(_name_) _name_##$$Base
|
||||
#define SECTION_END(_name_) _name_##$$Limit
|
||||
#define IMAGE_SECTION_START(_name_) Image$$##_name_##$$Base
|
||||
#define IMAGE_SECTION_END(_name_) Image$$##_name_##$$Limit
|
||||
#define CSTACK_BLOCK_START(_name_) SECTION_START(_name_)
|
||||
#define CSTACK_BLOCK_END(_name_) SECTION_END(_name_)
|
||||
#define CODE_SECTION_START(_name_) IMAGE_SECTION_START(_name_)
|
||||
#define CODE_SECTION_END(_name_) IMAGE_SECTION_END(_name_)
|
||||
|
||||
extern const int CSTACK_BLOCK_START(DEFAULT_CSTACK_SECTION_NAME);
|
||||
extern const int CSTACK_BLOCK_END(DEFAULT_CSTACK_SECTION_NAME);
|
||||
extern const int CODE_SECTION_START(DEFAULT_CODE_SECTION_NAME);
|
||||
extern const int CODE_SECTION_END(DEFAULT_CODE_SECTION_NAME);
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_code_start(void)
|
||||
{
|
||||
return (cpu_addr_t)&CODE_SECTION_START(DEFAULT_CODE_SECTION_NAME);
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_code_limit(void)
|
||||
{
|
||||
return (cpu_addr_t)&CODE_SECTION_END(DEFAULT_CODE_SECTION_NAME);
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_msp_start(void)
|
||||
{
|
||||
return (cpu_addr_t)&CSTACK_BLOCK_START(DEFAULT_CSTACK_SECTION_NAME);
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_msp_limit(void)
|
||||
{
|
||||
return (cpu_addr_t)&CSTACK_BLOCK_END(DEFAULT_CSTACK_SECTION_NAME);
|
||||
}
|
||||
|
||||
#elif defined(__ICCARM__)
|
||||
|
||||
#define DEFAULT_CODE_SECTION_NAME ".text"
|
||||
#define DEFAULT_CSTACK_SECTION_NAME "CSTACK"
|
||||
|
||||
#pragma section=DEFAULT_CSTACK_SECTION_NAME
|
||||
#pragma section=DEFAULT_CODE_SECTION_NAME
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_code_start(void)
|
||||
{
|
||||
return (cpu_addr_t)__section_begin(DEFAULT_CODE_SECTION_NAME);
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_code_limit(void)
|
||||
{
|
||||
return (cpu_addr_t)__section_end(DEFAULT_CODE_SECTION_NAME);
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_msp_start(void)
|
||||
{
|
||||
return (cpu_addr_t)__section_begin(DEFAULT_CSTACK_SECTION_NAME);
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_msp_limit(void)
|
||||
{
|
||||
return (cpu_addr_t)__section_end(DEFAULT_CSTACK_SECTION_NAME);
|
||||
}
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
/**
|
||||
* if we are using keil(armcc) or mdk(iccarm), we probably use the defult link script supplied by the IDE.
|
||||
* the way to locate the text/stack section start and limit is to find them in default link script.
|
||||
* but if we build our project by makefile(or something like scons, cmake, etc), we probably need to write
|
||||
* our own link scrpit, if so, we should do like this(just a demo):
|
||||
*
|
||||
_stext = .;
|
||||
.text : {
|
||||
*(.text.startup)
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
}
|
||||
_etext = .;
|
||||
|
||||
__bss_start = .;
|
||||
.bss : {
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(COMMON)
|
||||
_sstack = .;
|
||||
*(.cstack)
|
||||
_estack = .;
|
||||
}
|
||||
__bss_end = .;
|
||||
* by this, we can locate text/stack section start and limit by _stext/_etext and _sstack/_estack
|
||||
*/
|
||||
#define DEFAULT_CODE_SECTION_START _stext
|
||||
#define DEFAULT_CODE_SECTION_END _etext
|
||||
#define DEFAULT_CSTACK_SECTION_START _sstack
|
||||
#define DEFAULT_CSTACK_SECTION_END _estack
|
||||
|
||||
extern const int DEFAULT_CODE_SECTION_START;
|
||||
extern const int DEFAULT_CODE_SECTION_END;
|
||||
|
||||
extern const int DEFAULT_CSTACK_SECTION_START;
|
||||
extern const int DEFAULT_CSTACK_SECTION_END;
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_code_start(void)
|
||||
{
|
||||
return (cpu_addr_t)(&(DEFAULT_CODE_SECTION_START));
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_code_limit(void)
|
||||
{
|
||||
return (cpu_addr_t)(&(DEFAULT_CODE_SECTION_END));
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_msp_start(void)
|
||||
{
|
||||
return (cpu_addr_t)(&(DEFAULT_CSTACK_SECTION_START));
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ cpu_addr_t fault_msp_limit(void)
|
||||
{
|
||||
return (cpu_addr_t)(&(DEFAULT_CSTACK_SECTION_END));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
__API__ void tos_fault_log_writer_set(k_fault_log_writer_t log_writer);
|
||||
|
||||
__KNL__ int fault_default_log_writer(const char *format, ...);
|
||||
|
||||
__KNL__ void fault_backtrace(cpu_addr_t lr, fault_exc_frame_t *frame);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _TOS_FAULT_H_ */
|
||||
|
|
@ -0,0 +1,293 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos_k.h"
|
||||
|
||||
__API__ uint32_t tos_cpu_clz(uint32_t val)
|
||||
{
|
||||
#if defined(TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT) && (TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT == 0u)
|
||||
uint32_t nbr_lead_zeros = 0;
|
||||
|
||||
if (!(val & 0XFFFF0000)) {
|
||||
val <<= 16;
|
||||
nbr_lead_zeros += 16;
|
||||
}
|
||||
|
||||
if (!(val & 0XFF000000)) {
|
||||
val <<= 8;
|
||||
nbr_lead_zeros += 8;
|
||||
}
|
||||
|
||||
if (!(val & 0XF0000000)) {
|
||||
val <<= 4;
|
||||
nbr_lead_zeros += 4;
|
||||
}
|
||||
|
||||
if (!(val & 0XC0000000)) {
|
||||
val <<= 2;
|
||||
nbr_lead_zeros += 2;
|
||||
}
|
||||
|
||||
if (!(val & 0X80000000)) {
|
||||
nbr_lead_zeros += 1;
|
||||
}
|
||||
|
||||
if (!val) {
|
||||
nbr_lead_zeros += 1;
|
||||
}
|
||||
|
||||
return (nbr_lead_zeros);
|
||||
#else
|
||||
return port_clz(val);
|
||||
#endif
|
||||
}
|
||||
|
||||
__API__ void tos_cpu_int_disable(void)
|
||||
{
|
||||
port_int_disable();
|
||||
}
|
||||
|
||||
__API__ void tos_cpu_int_enable(void)
|
||||
{
|
||||
port_int_enable();
|
||||
}
|
||||
|
||||
__API__ cpu_cpsr_t tos_cpu_cpsr_save(void)
|
||||
{
|
||||
return port_cpsr_save();
|
||||
}
|
||||
|
||||
__API__ void tos_cpu_cpsr_restore(cpu_cpsr_t cpsr)
|
||||
{
|
||||
port_cpsr_restore(cpsr);
|
||||
}
|
||||
|
||||
__KNL__ void cpu_init(void)
|
||||
{
|
||||
k_cpu_cycle_per_tick = TOS_CFG_CPU_CLOCK / k_cpu_tick_per_second;
|
||||
cpu_systick_init(k_cpu_cycle_per_tick);
|
||||
|
||||
#if (TOS_CFG_CPU_HRTIMER_EN > 0)
|
||||
tos_cpu_hrtimer_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
__KNL__ void cpu_reset(void)
|
||||
{
|
||||
port_cpu_reset();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_sched_start(void)
|
||||
{
|
||||
port_sched_start();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_context_switch(void)
|
||||
{
|
||||
port_context_switch();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_irq_context_switch(void)
|
||||
{
|
||||
port_irq_context_switch();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_systick_init(k_cycle_t cycle_per_tick)
|
||||
{
|
||||
port_systick_priority_set(TOS_CFG_CPU_SYSTICK_PRIO);
|
||||
port_systick_config(cycle_per_tick);
|
||||
}
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN > 0u
|
||||
|
||||
/**
|
||||
* @brief Set value to systick reload value register
|
||||
*
|
||||
* @param cycles The value set to register
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__STATIC_INLINE__ void cpu_systick_reload(k_cycle_t cycle_per_tick)
|
||||
{
|
||||
port_systick_reload(cycle_per_tick);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable systick interrupt
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__KNL__ void cpu_systick_resume(void)
|
||||
{
|
||||
port_systick_resume();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable systick interrupt
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__KNL__ void cpu_systick_suspend(void)
|
||||
{
|
||||
port_systick_suspend();
|
||||
}
|
||||
|
||||
__KNL__ k_time_t cpu_systick_max_delay_millisecond(void)
|
||||
{
|
||||
return port_systick_max_delay_millisecond();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_systick_expires_set(k_time_t millisecond)
|
||||
{
|
||||
k_cycle_t cycles;
|
||||
|
||||
cycles = (k_cycle_t)((uint64_t)millisecond * TOS_CFG_CPU_CLOCK / K_TIME_MILLISEC_PER_SEC); /* CLOCK means cycle per second */
|
||||
|
||||
cpu_systick_reload(cycles - 12); /* interrupt delay */
|
||||
}
|
||||
|
||||
__KNL__ void cpu_systick_pending_reset(void)
|
||||
{
|
||||
port_systick_pending_reset();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_systick_reset(void)
|
||||
{
|
||||
cpu_systick_reload(k_cpu_cycle_per_tick);
|
||||
}
|
||||
|
||||
#endif /* TOS_CFG_TICKLESS_EN */
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__KNL__ void cpu_sleep_mode_enter(void)
|
||||
{
|
||||
port_sleep_mode_enter();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_stop_mode_enter(void)
|
||||
{
|
||||
port_stop_mode_enter();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_standby_mode_enter(void)
|
||||
{
|
||||
port_standby_mode_enter();
|
||||
}
|
||||
|
||||
#endif /* TOS_CFG_PWR_MGR_EN */
|
||||
|
||||
__KNL__ k_stack_t *cpu_task_stk_init(void *entry,
|
||||
void *arg,
|
||||
void *exit,
|
||||
k_stack_t *stk_base,
|
||||
size_t stk_size)
|
||||
{
|
||||
cpu_data_t *sp;
|
||||
|
||||
sp = (cpu_data_t *)&stk_base[stk_size];
|
||||
sp = (cpu_data_t *)((cpu_addr_t)sp & 0xFFFFFFF8);
|
||||
|
||||
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
|
||||
uint8_t *slot = (uint8_t *)&stk_base[0];
|
||||
for (; slot < (uint8_t *)sp; ++slot) {
|
||||
*slot = 0xCC;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* auto-saved on exception(pendSV) by hardware */
|
||||
*--sp = (cpu_data_t)0x01000000u; /* xPSR */
|
||||
*--sp = (cpu_data_t)entry; /* entry */
|
||||
*--sp = (cpu_data_t)exit; /* R14 (LR) */
|
||||
*--sp = (cpu_data_t)0x12121212u; /* R12 */
|
||||
*--sp = (cpu_data_t)0x03030303u; /* R3 */
|
||||
*--sp = (cpu_data_t)0x02020202u; /* R2 */
|
||||
*--sp = (cpu_data_t)0x01010101u; /* R1 */
|
||||
*--sp = (cpu_data_t)arg; /* R0: arg */
|
||||
|
||||
/* Remaining registers saved on process stack */
|
||||
/* EXC_RETURN = 0xFFFFFFFDL
|
||||
Initial state: Thread mode + non-floating-point state + PSP
|
||||
31 - 28 : EXC_RETURN flag, 0xF
|
||||
27 - 5 : reserved, 0xFFFFFE
|
||||
4 : 1, basic stack frame; 0, extended stack frame
|
||||
3 : 1, return to Thread mode; 0, return to Handler mode
|
||||
2 : 1, return to PSP; 0, return to MSP
|
||||
1 : reserved, 0
|
||||
0 : reserved, 1
|
||||
*/
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
*--sp = (cpu_data_t)0xFFFFFFFDL;
|
||||
#endif
|
||||
|
||||
*--sp = (cpu_data_t)0x11111111u; /* R11 */
|
||||
*--sp = (cpu_data_t)0x10101010u; /* R10 */
|
||||
*--sp = (cpu_data_t)0x09090909u; /* R9 */
|
||||
*--sp = (cpu_data_t)0x08080808u; /* R8 */
|
||||
*--sp = (cpu_data_t)0x07070707u; /* R7 */
|
||||
*--sp = (cpu_data_t)0x06060606u; /* R6 */
|
||||
*--sp = (cpu_data_t)0x05050505u; /* R5 */
|
||||
*--sp = (cpu_data_t)0x04040404u; /* R4 */
|
||||
|
||||
return (k_stack_t *)sp;
|
||||
}
|
||||
|
||||
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
|
||||
|
||||
__KNL__ k_err_t cpu_task_stack_draught_depth(k_stack_t *stk_base, size_t stk_size, int *depth)
|
||||
{
|
||||
uint8_t *slot;
|
||||
uint8_t *sp, *bp;
|
||||
int the_depth = 0;
|
||||
|
||||
bp = (uint8_t *)&stk_base[0];
|
||||
|
||||
sp = &stk_base[stk_size];
|
||||
sp = (uint8_t *)((cpu_addr_t)sp & 0xFFFFFFF8);
|
||||
|
||||
for (slot = sp - 1; slot >= bp; --slot) {
|
||||
if (*slot != 0xCC) {
|
||||
the_depth = sp - slot;
|
||||
}
|
||||
}
|
||||
|
||||
*depth = the_depth;
|
||||
if (the_depth == stk_size) {
|
||||
return K_ERR_TASK_STK_OVERFLOW;
|
||||
}
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
__KNL__ void cpu_flush_fpu(void)
|
||||
{
|
||||
(void)__get_FPSCR();
|
||||
}
|
||||
#endif
|
||||
|
||||
__KNL__ void cpu_fault_diagnosis(void)
|
||||
{
|
||||
port_fault_diagnosis();
|
||||
}
|
||||
|
||||
#endif /* TOS_CFG_FAULT_BACKTRACE_EN */
|
||||
|
|
@ -0,0 +1,270 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos_k.h"
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
|
||||
__STATIC_INLINE__ void fault_spin(void)
|
||||
{
|
||||
tos_knl_sched_lock();
|
||||
tos_cpu_int_disable();
|
||||
while (K_TRUE) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/* EXC_RETURN:
|
||||
31 - 28 : EXC_RETURN flag
|
||||
27 - 5 : reserved
|
||||
4 : 1, basic stack frame; 0, extended stack frame
|
||||
3 : 1, return to Thread mode; 0, return to Handler mode
|
||||
2 : 1, return to PSP; 0, return to MSP
|
||||
1 : reserved, 0
|
||||
0 : reserved, 1
|
||||
*/
|
||||
__STATIC_INLINE__ int fault_is_on_task(cpu_data_t lr)
|
||||
{
|
||||
return (lr & (1u << 2)) != 0;
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ int fault_is_thumb(cpu_data_t psr)
|
||||
{
|
||||
return (psr & (1u << 24)) != 0;
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ int fault_is_code(fault_info_t *info, cpu_data_t value)
|
||||
{
|
||||
return value >= info->code_start && value <= info->code_limit;
|
||||
}
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
__STATIC_INLINE__ int fault_is_extended_stack_frame(cpu_data_t lr)
|
||||
{
|
||||
return (lr & (1u << 4)) == 0;
|
||||
}
|
||||
|
||||
__STATIC__ void fault_dump_fpu_frame(fault_fpu_frame_t *fpu_frame)
|
||||
{
|
||||
/*
|
||||
* As known, v7-m has a feature named "LAZY PUSH", for the reason we do not do any float
|
||||
* operation in fault_backtrace, cpu will not do the real fpu register push to the stack.
|
||||
* that means the value we dump in fault_dump_fpu_frame will not be the correct value of
|
||||
* each FPU register.
|
||||
* We define a function here which access to FPSCR, if this function involved, cpu will do
|
||||
* the real FPU register push so we will get the correct dump.
|
||||
* I know it's ugly, but it works. If you know a better way, please tell me.
|
||||
*/
|
||||
cpu_flush_fpu();
|
||||
|
||||
k_fault_log_writer("\n\n====================== FPU Registers =======================\n");
|
||||
k_fault_log_writer(" %s: %08x\n", "FPSCR", fpu_frame->fpscr);
|
||||
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||
"S0 ", fpu_frame->s0,
|
||||
"S1 ", fpu_frame->s1,
|
||||
"S2 ", fpu_frame->s2,
|
||||
"S3 ", fpu_frame->s3);
|
||||
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||
"S4 ", fpu_frame->s4,
|
||||
"S5 ", fpu_frame->s5,
|
||||
"S6 ", fpu_frame->s6,
|
||||
"S7 ", fpu_frame->s7);
|
||||
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||
"S8 ", fpu_frame->s8,
|
||||
"S9 ", fpu_frame->s9,
|
||||
"S10", fpu_frame->s10,
|
||||
"S11", fpu_frame->s11);
|
||||
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||
"S12", fpu_frame->s12,
|
||||
"S13", fpu_frame->s13,
|
||||
"S14", fpu_frame->s14,
|
||||
"S15", fpu_frame->s15);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
__STATIC__ void fault_dump_cpu_frame(fault_cpu_frame_t *cpu_frame)
|
||||
{
|
||||
k_fault_log_writer("\n\n====================== CPU Registers =======================\n");
|
||||
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||
"R0 ", cpu_frame->r0,
|
||||
"R1 ", cpu_frame->r1,
|
||||
"R2 ", cpu_frame->r2,
|
||||
"R3 ", cpu_frame->r3);
|
||||
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||
"R12", cpu_frame->r12,
|
||||
"LR ", cpu_frame->lr,
|
||||
"PC ", cpu_frame->pc,
|
||||
"PSR", cpu_frame->spsr);
|
||||
}
|
||||
|
||||
__STATIC__ void fault_dump_stack(fault_info_t *info, size_t depth)
|
||||
{
|
||||
cpu_addr_t sp = info->sp_before_fault;
|
||||
|
||||
k_fault_log_writer("\nTASK STACK DUMP:\n");
|
||||
while (sp <= info->stack_limit && depth--) {
|
||||
k_fault_log_writer(" addr: %08x data: %08x\n", sp, (cpu_data_t)*(cpu_data_t *)sp);
|
||||
sp += sizeof(cpu_addr_t);
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC__ void fault_call_stack_backtrace(fault_info_t *info, size_t depth)
|
||||
{
|
||||
cpu_data_t value;
|
||||
cpu_addr_t sp = info->sp_before_fault;
|
||||
|
||||
if (info->is_stk_ovrf) {
|
||||
return;
|
||||
}
|
||||
|
||||
k_fault_log_writer("\n\n====================== Dump Call Stack =====================\n");
|
||||
|
||||
k_fault_log_writer("%08x", info->pc);
|
||||
|
||||
/* walk through the stack, check every content on stack whether is a instruction(code) */
|
||||
for (; sp < info->stack_limit && depth; sp += sizeof(cpu_addr_t)) {
|
||||
value = *((cpu_addr_t *)sp) - sizeof(cpu_addr_t);
|
||||
|
||||
/* if thumb, a instruction's first bit must be 1 */
|
||||
if (info->is_thumb && !(value & 1)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fault_is_code(info, value)) {
|
||||
k_fault_log_writer(" %08x\n", value);
|
||||
--depth;
|
||||
}
|
||||
}
|
||||
|
||||
k_fault_log_writer("\nusage: addr2line -e <*.axf> -a -f <dump call stack>");
|
||||
}
|
||||
|
||||
__STATIC__ void fault_dump_task(fault_info_t *info)
|
||||
{
|
||||
k_task_t *task;
|
||||
|
||||
if (!info->is_on_task) {
|
||||
return;
|
||||
}
|
||||
|
||||
task = k_curr_task;
|
||||
k_fault_log_writer("\n\n====================== Fault on task =======================\n");
|
||||
k_fault_log_writer(" TASK NAME: %s\n", task->name);
|
||||
k_fault_log_writer(" STK BASE: %x\n", info->stack_start);
|
||||
k_fault_log_writer(" STK SIZE: %x\n", task->stk_size * sizeof(k_stack_t));
|
||||
k_fault_log_writer(" STK LIMIT: %x\n", info->stack_limit);
|
||||
|
||||
if (!info->is_stk_ovrf) {
|
||||
fault_dump_stack(info, K_FAULT_STACK_DUMP_DEPTH);
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC__ void fault_dump_information(fault_info_t *info)
|
||||
{
|
||||
k_fault_log_writer("\n\n================== Dump Fault Information ==================\n");
|
||||
k_fault_log_writer(" THUMB: %s\n", info->is_thumb ? "TRUE" : "FALSE");
|
||||
k_fault_log_writer(" ON TASK: %s\n", info->is_on_task? "TRUE" : "FALSE");
|
||||
k_fault_log_writer(" STK OVRF: %s\n", info->is_stk_ovrf? "TRUE" : "FALSE");
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
k_fault_log_writer(" EXT STK: %s\n", info->is_ext_stk_frm? "TRUE" : "FALSE");
|
||||
#endif
|
||||
|
||||
k_fault_log_writer(" PC: %08x\n", info->pc);
|
||||
k_fault_log_writer(" SP: %08x\n", info->sp_before_fault);
|
||||
k_fault_log_writer(" STK START: %08x\n", info->stack_start);
|
||||
k_fault_log_writer(" STK LIMIT: %08x\n", info->stack_limit);
|
||||
k_fault_log_writer(" COD START: %08x\n", info->code_start);
|
||||
k_fault_log_writer(" COD LIMIT: %08x\n", info->code_limit);
|
||||
}
|
||||
|
||||
__STATIC__ void fault_gather_information(cpu_data_t lr, fault_exc_frame_t *frame, fault_info_t *info)
|
||||
{
|
||||
info->is_thumb = fault_is_thumb(frame->cpu_frame.spsr);
|
||||
info->is_on_task = fault_is_on_task(lr);
|
||||
|
||||
info->pc = frame->cpu_frame.pc;
|
||||
|
||||
info->sp_before_fault = (cpu_addr_t)frame + sizeof(fault_cpu_frame_t);
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
info->is_ext_stk_frm = fault_is_extended_stack_frame(lr);
|
||||
|
||||
if (info->is_ext_stk_frm) {
|
||||
info->sp_before_fault += sizeof(fault_fpu_frame_t);
|
||||
}
|
||||
#endif
|
||||
|
||||
info->code_start = fault_code_start();
|
||||
info->code_limit = fault_code_limit();
|
||||
|
||||
if (info->is_on_task) {
|
||||
info->stack_start = (cpu_addr_t)k_curr_task->stk_base;
|
||||
info->stack_limit = info->stack_start + k_curr_task->stk_size;
|
||||
} else {
|
||||
info->stack_start = fault_msp_start();
|
||||
info->stack_limit = fault_msp_limit();
|
||||
}
|
||||
|
||||
info->is_stk_ovrf = (info->sp_before_fault < info->stack_start || info->sp_before_fault > info->stack_limit);
|
||||
}
|
||||
|
||||
__KNL__ int fault_default_log_writer(const char *format, ...)
|
||||
{
|
||||
int len;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
len = vprintf(format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
__API__ void tos_fault_log_writer_set(k_fault_log_writer_t log_writer)
|
||||
{
|
||||
k_fault_log_writer = log_writer;
|
||||
}
|
||||
|
||||
__KNL__ void fault_backtrace(cpu_addr_t lr, fault_exc_frame_t *frame)
|
||||
{
|
||||
fault_info_t info;
|
||||
|
||||
fault_gather_information(lr, frame, &info);
|
||||
|
||||
fault_dump_information(&info);
|
||||
|
||||
fault_dump_task(&info);
|
||||
|
||||
fault_dump_cpu_frame(&frame->cpu_frame);
|
||||
|
||||
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||
if (info.is_ext_stk_frm) {
|
||||
fault_dump_fpu_frame(&frame->fpu_frame);
|
||||
}
|
||||
#endif
|
||||
|
||||
fault_call_stack_backtrace(&info, K_FAULT_CALL_STACK_BACKTRACE_DEPTH);
|
||||
|
||||
cpu_fault_diagnosis();
|
||||
|
||||
fault_spin();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _PORT_H_
|
||||
#define _PORT_H_
|
||||
|
||||
__PORT__ void port_int_disable(void);
|
||||
|
||||
__PORT__ void port_int_enable(void);
|
||||
|
||||
__PORT__ cpu_cpsr_t port_cpsr_save(void);
|
||||
|
||||
__PORT__ void port_cpsr_restore(cpu_cpsr_t cpsr);
|
||||
|
||||
__PORT__ void port_cpu_reset(void);
|
||||
|
||||
__PORT__ void port_sched_start(void) __NO_RETURN__;
|
||||
|
||||
__PORT__ void port_context_switch(void);
|
||||
|
||||
__PORT__ void port_irq_context_switch(void);
|
||||
|
||||
__PORT__ void port_systick_config(uint32_t cycle_per_tick);
|
||||
|
||||
__PORT__ void port_systick_priority_set(uint32_t prio);
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN > 0u
|
||||
|
||||
__PORT__ void port_systick_resume(void);
|
||||
|
||||
__PORT__ void port_systick_suspend(void);
|
||||
|
||||
__PORT__ void port_systick_reload(uint32_t cycle_per_tick);
|
||||
|
||||
__PORT__ void port_systick_pending_reset(void);
|
||||
|
||||
__PORT__ k_time_t port_systick_max_delay_millisecond(void);
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__PORT__ void port_sleep_mode_enter(void);
|
||||
|
||||
__PORT__ void port_stop_mode_enter(void);
|
||||
|
||||
__PORT__ void port_standby_mode_enter(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
__PORT__ void HardFault_Handler(void);
|
||||
|
||||
__PORT__ void port_fault_diagnosis(void);
|
||||
#endif
|
||||
|
||||
#endif /* _PORT_H_ */
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos_k.h"
|
||||
#include "core_cm0plus.h"
|
||||
|
||||
__PORT__ void port_cpu_reset(void)
|
||||
{
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_config(uint32_t cycle_per_tick)
|
||||
{
|
||||
(void)SysTick_Config(cycle_per_tick);
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_priority_set(uint32_t prio)
|
||||
{
|
||||
NVIC_SetPriority(SysTick_IRQn, prio);
|
||||
}
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN > 0u
|
||||
|
||||
__PORT__ k_time_t port_systick_max_delay_millisecond(void)
|
||||
{
|
||||
k_time_t max_millisecond;
|
||||
uint32_t max_cycle;
|
||||
|
||||
max_cycle = SysTick_LOAD_RELOAD_Msk; // 24 bit
|
||||
max_millisecond = (k_time_t)((uint64_t)max_cycle * K_TIME_MILLISEC_PER_SEC / TOS_CFG_CPU_CLOCK); // CLOCK: cycle per second
|
||||
return max_millisecond;
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_resume(void)
|
||||
{
|
||||
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
|
||||
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_suspend(void)
|
||||
{
|
||||
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
|
||||
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_reload(uint32_t cycle_per_tick)
|
||||
{
|
||||
port_systick_config(cycle_per_tick);
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_pending_reset(void)
|
||||
{
|
||||
SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__PORT__ void port_sleep_mode_enter(void)
|
||||
{
|
||||
#if 1
|
||||
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
|
||||
#else
|
||||
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
|
||||
#endif
|
||||
}
|
||||
|
||||
__PORT__ void port_stop_mode_enter(void)
|
||||
{
|
||||
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
|
||||
}
|
||||
|
||||
__PORT__ void port_standby_mode_enter(void)
|
||||
{
|
||||
HAL_PWR_EnterSTANDBYMode();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
__PORT__ void port_fault_diagnosis(void)
|
||||
{
|
||||
k_fault_log_writer("fault diagnosis is not supported in CORTEX M0+\n");
|
||||
}
|
||||
|
||||
/*------------------ RealView Compiler -----------------*/
|
||||
/* V5 */
|
||||
#if defined(__CC_ARM)
|
||||
|
||||
__PORT__ __ASM__ void HardFault_Handler(void)
|
||||
{
|
||||
IMPORT fault_backtrace
|
||||
|
||||
MOV r0, lr
|
||||
MOVS r1, #0x04
|
||||
TST r0, r1
|
||||
BEQ _LD_MSP
|
||||
MRS r1, PSP
|
||||
B _EXIT
|
||||
|
||||
_LD_MSP
|
||||
MRS r1, MSP
|
||||
|
||||
_EXIT
|
||||
BL fault_backtrace
|
||||
}
|
||||
|
||||
/*------------------ ARM Compiler V6 -------------------*/
|
||||
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
|
||||
__PORT__ void __NAKED__ HardFault_Handler(void)
|
||||
{
|
||||
__ASM__ __VOLATILE__ (
|
||||
"MOV r0, lr\n\t"
|
||||
"MOVS r1, #0x04\n\t"
|
||||
"TST r0, r1\n\t"
|
||||
"BEQ _LD_MSP\n\t"
|
||||
"MRS r1, PSP\n\t"
|
||||
"B _EXIT\n\t"
|
||||
"_LD_MSP:\n\t"
|
||||
"MRS r1, MSP\n\t"
|
||||
"_EXIT:\n\t"
|
||||
"BL fault_backtrace\n\t"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* ARMCC VERSION */
|
||||
|
||||
#endif /* TOS_CFG_FAULT_BACKTRACE_EN */
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _PORT_CONFIG_H_
|
||||
#define _PORT_CONFIG_H_
|
||||
|
||||
#define TOS_CFG_CPU_ADDR_SIZE CPU_WORD_SIZE_32
|
||||
#define TOS_CFG_CPU_DATA_SIZE CPU_WORD_SIZE_32
|
||||
#define TOS_CFG_CPU_STK_GROWTH CPU_STK_GROWTH_DESCENDING
|
||||
// #define TOS_CFG_CPU_HRTIMER_SIZE CPU_WORD_SIZE_32
|
||||
#define TOS_CFG_CPU_HRTIMER_EN 0u
|
||||
#define TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT 0u
|
||||
#define TOS_CFG_CPU_BYTE_ORDER CPU_BYTE_ORDER_LITTLE_ENDIAN
|
||||
|
||||
#endif /* _PORT_CONFIG_H_ */
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
EXPORT port_int_disable
|
||||
EXPORT port_int_enable
|
||||
|
||||
EXPORT port_cpsr_save
|
||||
EXPORT port_cpsr_restore
|
||||
|
||||
EXPORT port_sched_start
|
||||
EXPORT port_context_switch
|
||||
EXPORT port_irq_context_switch
|
||||
|
||||
EXPORT PendSV_Handler
|
||||
|
||||
IMPORT k_curr_task
|
||||
IMPORT k_next_task
|
||||
|
||||
|
||||
NVIC_INT_CTRL EQU 0xE000ED04 ; Interrupt control state register.
|
||||
NVIC_SYSPRI14 EQU 0xE000ED20 ; System priority register (priority 14).
|
||||
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest).
|
||||
NVIC_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception.
|
||||
|
||||
|
||||
AREA |.text|, CODE, READONLY, ALIGN=2
|
||||
THUMB
|
||||
REQUIRE8
|
||||
PRESERVE8
|
||||
|
||||
GLOBAL port_int_disable
|
||||
port_int_disable
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
|
||||
GLOBAL port_int_enable
|
||||
port_int_enable
|
||||
CPSIE I
|
||||
BX LR
|
||||
|
||||
|
||||
GLOBAL port_cpsr_save
|
||||
port_cpsr_save
|
||||
MRS R0, PRIMASK
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
|
||||
GLOBAL port_cpsr_restore
|
||||
port_cpsr_restore
|
||||
MSR PRIMASK, R0
|
||||
BX LR
|
||||
|
||||
|
||||
GLOBAL port_sched_start
|
||||
port_sched_start
|
||||
LDR R0, =NVIC_SYSPRI14
|
||||
LDR R1, =NVIC_PENDSV_PRI
|
||||
STR R1, [R0]
|
||||
|
||||
MOVS R0, #0
|
||||
MSR PSP, R0
|
||||
|
||||
LDR R0, =NVIC_INT_CTRL
|
||||
LDR R1, =NVIC_PENDSVSET
|
||||
STR R1, [R0]
|
||||
|
||||
CPSIE I
|
||||
|
||||
__unreachable
|
||||
B __unreachable
|
||||
|
||||
|
||||
GLOBAL port_context_switch
|
||||
port_context_switch
|
||||
LDR R0, =NVIC_INT_CTRL
|
||||
LDR R1, =NVIC_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
|
||||
GLOBAL port_irq_context_switch
|
||||
port_irq_context_switch
|
||||
LDR R0, =NVIC_INT_CTRL
|
||||
LDR R1, =NVIC_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
|
||||
GLOBAL PendSV_Handler
|
||||
PendSV_Handler
|
||||
CPSID I
|
||||
MRS R0, PSP
|
||||
CMP R0, #0
|
||||
BEQ PendSVHandler_nosave
|
||||
|
||||
SUBS R0, R0, #0x20
|
||||
STMIA R0!, {R4 - R7}
|
||||
MOV R4, R8
|
||||
MOV R5, R9
|
||||
MOV R6, R10
|
||||
MOV R7, R11
|
||||
STMIA R0!, {R4-R7}
|
||||
SUBS R0, R0, #0x20
|
||||
|
||||
LDR R1, =k_curr_task
|
||||
LDR R1, [R1]
|
||||
STR R0, [R1]
|
||||
|
||||
PendSVHandler_nosave
|
||||
LDR R0, =k_curr_task
|
||||
LDR R1, =k_next_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
|
||||
LDR R0, [R2]
|
||||
|
||||
LDMIA R0!, {R4 - R7}
|
||||
LDMIA R0!, {R2 - R3}
|
||||
MOV R8, R2
|
||||
MOV R9, R3
|
||||
LDMIA R0!, {R2 - R3}
|
||||
MOV R10, R2
|
||||
MOV R11, R3
|
||||
MSR PSP, R0
|
||||
|
||||
MOV R0, R14
|
||||
MOVS R1, #0x04
|
||||
ORRS R0, R1
|
||||
MOV R14, R0
|
||||
|
||||
CPSIE I
|
||||
|
||||
BX LR
|
||||
|
||||
ALIGN
|
||||
|
||||
END
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _PORT_H_
|
||||
#define _PORT_H_
|
||||
|
||||
__PORT__ void port_int_disable(void);
|
||||
|
||||
__PORT__ void port_int_enable(void);
|
||||
|
||||
__PORT__ cpu_cpsr_t port_cpsr_save(void);
|
||||
|
||||
__PORT__ void port_cpsr_restore(cpu_cpsr_t cpsr);
|
||||
|
||||
__PORT__ void port_cpu_reset(void);
|
||||
|
||||
__PORT__ void port_sched_start(void) __NO_RETURN__;
|
||||
|
||||
__PORT__ void port_context_switch(void);
|
||||
|
||||
__PORT__ void port_irq_context_switch(void);
|
||||
|
||||
__PORT__ void port_systick_config(uint32_t cycle_per_tick);
|
||||
|
||||
__PORT__ void port_systick_priority_set(uint32_t prio);
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN > 0u
|
||||
|
||||
__PORT__ void port_systick_resume(void);
|
||||
|
||||
__PORT__ void port_systick_suspend(void);
|
||||
|
||||
__PORT__ void port_systick_reload(uint32_t cycle_per_tick);
|
||||
|
||||
__PORT__ void port_systick_pending_reset(void);
|
||||
|
||||
__PORT__ k_time_t port_systick_max_delay_millisecond(void);
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__PORT__ void port_sleep_mode_enter(void);
|
||||
|
||||
__PORT__ void port_stop_mode_enter(void);
|
||||
|
||||
__PORT__ void port_standby_mode_enter(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
__PORT__ void HardFault_Handler(void);
|
||||
|
||||
__PORT__ void port_fault_diagnosis(void);
|
||||
#endif
|
||||
|
||||
#endif /* _PORT_H_ */
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos_k.h"
|
||||
#include "core_cm0plus.h"
|
||||
|
||||
__PORT__ void port_cpu_reset(void)
|
||||
{
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_config(uint32_t cycle_per_tick)
|
||||
{
|
||||
(void)SysTick_Config(cycle_per_tick);
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_priority_set(uint32_t prio)
|
||||
{
|
||||
NVIC_SetPriority(SysTick_IRQn, prio);
|
||||
}
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN > 0u
|
||||
|
||||
__PORT__ k_time_t port_systick_max_delay_millisecond(void)
|
||||
{
|
||||
k_time_t max_millisecond;
|
||||
uint32_t max_cycle;
|
||||
|
||||
max_cycle = SysTick_LOAD_RELOAD_Msk; // 24 bit
|
||||
max_millisecond = (k_time_t)((uint64_t)max_cycle * K_TIME_MILLISEC_PER_SEC / TOS_CFG_CPU_CLOCK); // CLOCK: cycle per second
|
||||
return max_millisecond;
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_resume(void)
|
||||
{
|
||||
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
|
||||
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_suspend(void)
|
||||
{
|
||||
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
|
||||
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_reload(uint32_t cycle_per_tick)
|
||||
{
|
||||
port_systick_config(cycle_per_tick);
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_pending_reset(void)
|
||||
{
|
||||
SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__PORT__ void port_sleep_mode_enter(void)
|
||||
{
|
||||
#if 1
|
||||
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
|
||||
#else
|
||||
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
|
||||
#endif
|
||||
}
|
||||
|
||||
__PORT__ void port_stop_mode_enter(void)
|
||||
{
|
||||
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
|
||||
}
|
||||
|
||||
__PORT__ void port_standby_mode_enter(void)
|
||||
{
|
||||
HAL_PWR_EnterSTANDBYMode();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
__PORT__ void port_fault_diagnosis(void)
|
||||
{
|
||||
k_fault_log_writer("fault diagnosis is not supported in CORTEX M0+\n");
|
||||
}
|
||||
|
||||
/*------------------ RealView Compiler -----------------*/
|
||||
/* V5 */
|
||||
#if defined(__CC_ARM)
|
||||
|
||||
__PORT__ __ASM__ void HardFault_Handler(void)
|
||||
{
|
||||
IMPORT fault_backtrace
|
||||
|
||||
MOV r0, lr
|
||||
TST lr, #0x04
|
||||
ITE EQ
|
||||
MRSEQ r1, MSP
|
||||
MRSNE r1, PSP
|
||||
BL fault_backtrace
|
||||
}
|
||||
|
||||
/*------------------ ARM Compiler V6 -------------------*/
|
||||
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
|
||||
__PORT__ void __NAKED__ HardFault_Handler(void)
|
||||
{
|
||||
__ASM__ __VOLATILE__ (
|
||||
"MOV r0, lr\n\t"
|
||||
"TST lr, #0x04\n\t"
|
||||
"ITE EQ\n\t"
|
||||
"MRSEQ r1, MSP\n\t"
|
||||
"MRSNE r1, PSP\n\t"
|
||||
"BL fault_backtrace\n\t"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* ARMCC VERSION */
|
||||
|
||||
#endif /* TOS_CFG_FAULT_BACKTRACE_EN */
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _PORT_CONFIG_H_
|
||||
#define _PORT_CONFIG_H_
|
||||
|
||||
#define TOS_CFG_CPU_ADDR_SIZE CPU_WORD_SIZE_32
|
||||
#define TOS_CFG_CPU_DATA_SIZE CPU_WORD_SIZE_32
|
||||
#define TOS_CFG_CPU_STK_GROWTH CPU_STK_GROWTH_DESCENDING
|
||||
// #define TOS_CFG_CPU_HRTIMER_SIZE CPU_WORD_SIZE_32
|
||||
#define TOS_CFG_CPU_HRTIMER_EN 0u
|
||||
#define TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT 0u
|
||||
#define TOS_CFG_CPU_BYTE_ORDER CPU_BYTE_ORDER_LITTLE_ENDIAN
|
||||
|
||||
#endif /* _PORT_CONFIG_H_ */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue