123
This commit is contained in:
commit
6709c81281
|
|
@ -0,0 +1,35 @@
|
|||
*.bak
|
||||
*.ddk
|
||||
*.edk
|
||||
*.lst
|
||||
*.lnp
|
||||
*.mpf
|
||||
*.mpj
|
||||
*.obj
|
||||
*.omf
|
||||
*.plg
|
||||
*.rpt
|
||||
*.tmp
|
||||
*.__i
|
||||
*.crf
|
||||
*.o
|
||||
*.d
|
||||
*.axf
|
||||
*.hex
|
||||
*.tra
|
||||
*.dep
|
||||
*.iex
|
||||
*.map
|
||||
*.swp
|
||||
.DS_Store
|
||||
board/**/build
|
||||
board/**/.settings
|
||||
board/*/MDK-ARM/DebugConfig/
|
||||
board/*/obj/
|
||||
board/*/MDK-ARM/Obj/
|
||||
board/*/MDK-ARM/RTE/
|
||||
board/*/MDK-ARM/*.uvguix.*
|
||||
board/*/MDK-ARM/EventRecorderStub.scvd
|
||||
board/*/MDK-ARM/*/*.htm
|
||||
board/*/MDK-ARM/*/*.build_log.htm
|
||||
board/**/settings/*
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
language: c
|
||||
|
||||
os: linux
|
||||
dist: trusty
|
||||
|
||||
|
||||
compiler: arm-none-eabi-gcc
|
||||
|
||||
|
||||
before_install:
|
||||
- sudo add-apt-repository ppa:team-gcc-arm-embedded/ppa -y
|
||||
- sudo apt-get update -q
|
||||
- sudo apt-get install gcc-arm-embedded -y
|
||||
|
||||
|
||||
script:
|
||||
- cd board/TencentOS_tiny_EVB_MX_Plus/GCC/hello_world
|
||||
- make
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
BSD 3-Clause License
|
||||
|
||||
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.
|
||||
|
||||
A copy of the BSD 3-Clause License is included in this file.
|
||||
|
||||
Other dependencies and licenses:
|
||||
|
||||
|
||||
Open Source Software Licensed Under the MIT License:
|
||||
|
||||
1. spiffs 0.3.7
|
||||
Copyright (c) 2013-2017 Peter Andersson (pelleplutt1976<at>gmail.com)
|
||||
|
||||
2. CmBacktrace 1.2.0
|
||||
Copyright (c) 2016-2018 Armink (armink.ztl@gmail.com)
|
||||
|
||||
Terms of the MIT License:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Open Source Software Licensed Under the Apache License, Version 2.0:
|
||||
|
||||
1. Mbedtls 2.13.0
|
||||
Copyright © 2008 - 2016 ARM Limited. All Rights Reserved.
|
||||
|
||||
2. CMSIS 5.5.1
|
||||
Copyright © 1995-2019 Arm Limited (or its affiliates). All rights reserved.
|
||||
|
||||
Terms of the Apache License, Version 2.0:
|
||||
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
||||
|
||||
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
|
||||
|
||||
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
||||
|
||||
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
||||
|
||||
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
||||
|
||||
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
|
||||
|
||||
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
||||
|
||||
a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
||||
|
||||
b) You must cause any modified files to carry prominent notices stating that You changed the files; and
|
||||
|
||||
c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
||||
|
||||
d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
|
||||
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work
|
||||
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
|
||||
Open Source Software Licensed under the Eclipse Distribution License - v 1.0
|
||||
|
||||
1. paho.mqtt.embedded-c v1.1.0
|
||||
Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors.
|
||||
All rights reserved.
|
||||
|
||||
Terms of the Eclipse Distribution License - v 1.0
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
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.
|
||||
Neither the name of the Eclipse Foundation, 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 OWNER 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.
|
||||
|
||||
|
||||
Open Source Software Licensed Under the BSD-style licenses but there is a significant feature.
|
||||
|
||||
1. FATFS R0.13c
|
||||
Copyright (C) 2018, ChaN, all right reserved.
|
||||
|
||||
Terms of the BSD-style licenses
|
||||
|
||||
FatFs module is an open source software. Redistribution and use of FatFs in source and binary forms, with or without modification, are permitted provided that the following condition is met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this condition and the following disclaimer.
|
||||
This software is provided by the copyright holder and contributors "AS IS" and any warranties related to this software are DISCLAIMED.
|
||||
|
||||
The copyright owner or contributors be NOT LIABLE for any damages caused by use of this software.
|
||||
|
||||
Therefore FatFs license is one of the BSD-style licenses but there is a significant feature. FatFs is mainly intended for embedded systems. In order to extend the usability for commercial products, the redistributions of FatFs in binary form, such as embedded code, binary library and any forms without source code, does not need to include about FatFs in the documentations. This is equivalent to the 1-clause BSD license. Of course FatFs is compatible with the most of open source software licenses including GNU GPL. When you redistribute the FatFs source code with any changes or create a fork, the license can also be changed to GNU GPL, BSD-style license or any open source software license that not conflict with FatFs license.
|
||||
|
||||
|
||||
Open Source Software Licensed Under the BSD 3-Clause License:
|
||||
|
||||
1. LWIP 2.0.3
|
||||
Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
|
||||
All rights reserved.
|
||||
|
||||
2. LoRaMac-node 4.4.2-rc.4
|
||||
Copyright (c) 2013, SEMTECH S.A.
|
||||
All rights reserved.
|
||||
|
||||
3. FreeCoAP v0.6
|
||||
Copyright (c) 2015 - 2017 Keith Cullen
|
||||
|
||||
4. mattconte/tlsf v3.1
|
||||
Copyright (c) 2006-2016 Matthew (Conte matt@baisoku.org)
|
||||
|
||||
Terms of the BSD 3-Clause License:
|
||||
|
||||
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 THL A29 Limited 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.
|
||||
|
||||
|
|
@ -0,0 +1,198 @@
|
|||
|
||||
# 开放原子开源基金会首批孵化项目
|
||||

|
||||
|
||||
[](https://github.com/Tencent/TencentOS-tiny/blob/master/LICENSE)
|
||||
[](https://github.com/Tencent/TencentOS-tiny/pulls)
|
||||
[](https://travis-ci.org/Tencent/TencentOS-tiny)
|
||||
|
||||
[(English Documents Available)](README_en.md)
|
||||
|
||||
# 一、TencentOS Tiny 简介
|
||||
|
||||
[TencentOS tiny](https://cloud.tencent.com/product/tos-tiny) 是腾讯面向物联网领域开发的实时操作系统,具有低功耗,低资源占用,模块化,安全可靠等特点,可有效提升物联网终端产品开发效率。TencentOS tiny 提供精简的 RTOS 内核,内核组件可裁剪可配置,可快速移植到多种主流 MCU (如 STM32 全系列)及模组芯片上。而且,基于 RTOS 内核提供了丰富的物联网组件,内部集成主流物联网协议栈(如 CoAP/MQTT/TLS/DTLS/LoRaWAN/NB-IoT 等),可助力物联网终端设备及业务快速接入腾讯云物联网平台。
|
||||
|
||||
|
||||
## 1、TencentOS tiny整体架构
|
||||
|
||||

|
||||
|
||||
TencentOS tiny 主体架构图,从下到上主要包括:
|
||||
|
||||
**CPU 库** :TencentOS tiny 支持的 CPU IP 核架构,当前主要支持 ARM Cortex M0/3/4/7,Cortex A7,RISC-V、MSP430、AVR、STM8 等。
|
||||
|
||||
**驱动管理层** :包括板级支持包(BSP,主要由 MCU 芯片厂家开发与维护)、硬件抽象层(HAL,主要由 TencentOS tiny 提供,方便不同芯片的适配与移植)、设备驱动(Drivers,例如 Wi-Fi、GPRS、LoRa 等模块的驱动程序)。
|
||||
|
||||
**内核** :TencentOS tiny 实时内核包括任务管理、实时调度、时间管理、中断管理、内存管理、异常处理、软件定时器、链表、消息队列、信号量、互斥锁、事件标志等模块。
|
||||
|
||||
**IoT 协议栈**:TencentOS tiny 提供 lwip、AT Adapter、SAL 层,支持不同的网络硬件,例如以太网、串口 Wi-Fi、GPRS、NB-IoT、4G 等通信模块。TCP/IP 网络协议栈上提供常用的物联网协议栈,例如 CoAP、MQTT,支撑终端业务快速接入腾讯云。
|
||||
|
||||
**安全框架**:TencentOS tiny 为了确保物联网终端数据传输安全以及设备认证安全,提供了完整的安全解决方案。安全框架提供的 DTLS 和 TLS 安全协议,加固了 COAP 及 MQTT 的传输层,可确保物联网终端在对接腾讯云时实现安全认证和数据加密;另外针对低资源的终端硬件,安全框架还提供与腾讯云 IoTHub 配套的密钥认证方案,确保资源受限设备也能在一定程度上实现设备安全认证。
|
||||
|
||||
**组件框架**:TencentOS tiny 提供文件系统、KV 存储、自组网、JS 引擎、低功耗框架、设备框架、OTA、调试工具链等一系列组件,供用户根据业务场景选用。
|
||||
|
||||
**开放 API(规划开发中)**:TencentOS tiny 将在协议中间件和框架层上提供开放 API 函数,方便用户调用中间件功能,使用户无需过多关心中间件具体实现,快速对接腾讯云,实现终端业务上云的需求,期望最大程度减少终端物联网产品开发周期,节省开发成本。
|
||||
|
||||
**示例应用**:TencentOS tiny 提供的示例代码,模块测试代码等,方便用户参考使用。
|
||||
|
||||
## 2、TencentOS tiny 优势
|
||||
|
||||
### (1).小体积
|
||||
最小内核:RAM 0.6KB,ROM 1.8KB
|
||||
典型 LoraWAN 及传感器应用:RAM 3.3KB,ROM 12KB
|
||||
### (2).低功耗
|
||||
休眠最低功耗低至 2uA
|
||||
支持外设功耗管理框架
|
||||
### (3).丰富的 IoT 组件
|
||||
集成主流 IoT 协议栈
|
||||
多种通信模组SAL层适配框架;
|
||||
支持 OTA 升级
|
||||
提供简单易用端云 API,加速用户业务接入腾讯云
|
||||
### (4).可靠的安全框架
|
||||
多样化的安全分级方案
|
||||
均衡安全需求&成本控制
|
||||
### (5).良好的可移植性
|
||||
内核及IoT组件高度解耦,提供标准适配层
|
||||
提供自动化移植工具,提升开发效率
|
||||
### (6).便捷的调试手段
|
||||
提供云化的最后一屏调试功能
|
||||
故障现场信息自动上传云平台,方便开发人员调试分析
|
||||
|
||||
## 3、TencentOS tiny携手合作伙伴共建IoT生态
|
||||
|
||||

|
||||
|
||||
TencentOS tiny 自开源发布以来也在努力发展合作伙伴,期待合作共赢,共同扩展 IoT 应用生态。目前已经与多家 MCU/IP 核厂家达成了合作,包括意法半导体、恩智浦半导体、兆易半导体、ARM、华大半导体、芯来科技等;也与无线 SOC 和模组厂家达成了广泛的合作关系,包括瑞兴恒方、国民技术、Nordic 蓝牙、亮牛半导体、有人物联网等,
|
||||
|
||||
除了MCU和模组外,TencentOS tiny 也积极推进终端产品及项目的落地,目前已经形成了AI智慧农业、智能货柜、智慧会议室等方案,并且在腾讯内部与微信支付、腾讯云智慧行业、 AI 平台部、腾讯微瓴、QQ family 达成内部合作,共同扩展行业生态;同时也开始积极发展外部客户,目前与深圳光合显示科技的墨水屏零售标签、鑫悦购充电桩等达成业务合作。TencentOS tiny 将携手合作伙伴为物联网终端厂家提供更优质的 IoT 终端软件解决方案,方便各种物联网设备快速接入腾讯云,共同扩展 IoT 生态,更好地支撑智慧城市、智能水表、智能家居、智能穿戴、车联网等多种行业应用。
|
||||
|
||||
欢迎 IoT 相关项目合作,有合作需求的请邮件联系 TencentOS tiny 官方工作人员,邮箱地址 : supowang@tencent.com
|
||||
|
||||
# 二、TencentOS tiny 代码目录
|
||||
- [TencentOS tiny 代码目录说明](./doc/09.Code_Directories.md)
|
||||
|
||||
# 三、TencentOS tiny 参考文档
|
||||
## 1、移植指南
|
||||
- [TencentOS tiny 移植指南(KEIL 版本)](./doc/10.Porting_Manual_for_KEIL.md)
|
||||
- [TencentOS tiny 移植指南(IAR 版本)](./doc/11.Porting_Manual_for_IAR.md)
|
||||
- [TencentOS tiny 移植指南(GCC 版本)](./doc/12.Porting_Manual_for_GCC.md)
|
||||
- [TencentOS tiny 移植指南(基于MDK pack)](./tools/mdk_pack/Documentation/README.md)
|
||||
- [TencentOS tiny 移植指南(基于STM32 CubeMx)](./tools/STM32CubeMX_pack/Documentation/README.md)
|
||||
|
||||
## 2、TencentOS tiny 开发指南
|
||||
- [TencentOS tiny 内核开发指南](./doc/04.Development_Manual.md)
|
||||
- [TencentOS tiny API 参考](./doc/05.SDK_Manual.md)
|
||||
- [TencentOS tiny 对接腾讯云 IoTHub 开发指南](./doc/08.QCloud_IoTHub_Quick_Start.md)
|
||||
|
||||
## 3、TencentOS tiny 腾讯云大学视频教程
|
||||
- [TencentOS tiny 端侧开发实践课](https://cloud.tencent.com/edu/paths/series/IoT)
|
||||
|
||||
# 四、TencentOS tiny 开源协议
|
||||
* TencentOS tiny 遵循 [BSD-3 开源许可协议](LICENSE)
|
||||
|
||||
|
||||
# 五、TencentOS tiny 支持的物联网平台
|
||||
TencentOS tiny 能支持物联网终端设备和业务快速接入[腾讯云物联网平台 IoT Explorer](https://cloud.tencent.com/product/iotexplorer)。
|
||||
|
||||
TencentOS tiny 结合腾讯云物联网开发平台 IoT Explorer,已经构筑起连接通讯芯片到云开发的能力,加上已经建设完成的国内最大规模 LoRa 网络,腾讯彻底打通从芯片通讯开发、网络支撑服务,物理设备定义管理,数据分析和多场景应用开发等全链条IoT云开发服务能力,重新定义了物联网开发模式,助力亿级设备多方式多模式低门槛接入腾讯云服务。作为物联网基础设施建设服务者,腾讯将持续打造开放的物联网生态体系,促进物联网生态良性发展。
|
||||
|
||||
# 六、TencentOS tiny 快速入门参考
|
||||
TencentOS tiny 联合合作伙伴(南京厚德物联网)设计了定制开发板,如下图:
|
||||

|
||||
|
||||
- [TencentOS tiny 定制开发板介绍页](http://www.holdiot.com/product/showproduct.php?id=8),开发者可以基于定制开发板进行快速入门学习,点击下载参考文档
|
||||
- [TencentOS-tiny 定制开发板入门指南](./doc/15.TencentOS_tiny_EVB_MX_Plus_Quick_Start.md)
|
||||
|
||||
# 七、贡献代码
|
||||
* 1. 在您自己的 GitHub 账户下 Fork TencentOS tiny 开源项目;
|
||||
* 2. 根据您的需求在本地 clone 一份 TencentOS tiny 代码;
|
||||
* 3. 您修改或者新增功能后,push 到您 fork 的远程分支;
|
||||
* 4. 创建 pull request,向 TencentOS tiny 官方开发分支提交合入请求;
|
||||
* 5. TencentOS tiny 研发团队会定期 review 代码,通过测试后合入。
|
||||
|
||||
# 八、加入TencentOS tiny官方QQ技术交流群
|
||||
|
||||
扫码加群,请备注 TencentOS tiny 开发者,工作人员会根据备注进行审核:
|
||||
|
||||

|
||||
|
||||
# 九、第三方开发者评测
|
||||
|
||||
1.基于 TencentOS tiny 的环境监测实战项目
|
||||
[【TencentOS tiny】环境监测实战项目最终完整版](https://www.bilibili.com/video/av73782956?from=search&seid=4421984671929108231)
|
||||
感谢阿正的贡献
|
||||
|
||||
|
||||
2.基于野火 stm32f103 开发板上移植的 TencentOS tiny 例程、源码剖析、视频讲解。
|
||||
感谢 CSDN 博客专家杰杰的贡献
|
||||
|
||||
## 简单上手:
|
||||
|
||||
- [超详细的 TencentOS tiny 移植到 STM32F103 全教程](https://blog.csdn.net/jiejiemcu/article/details/101034426)
|
||||
|
||||
## 深度源码分析:
|
||||
|
||||
- [【TencentOS tiny 学习】源码分析(1)——task](https://blog.csdn.net/jiejiemcu/article/details/99618912)
|
||||
|
||||
- [【TencentOS tiny 学习】源码分析(2)——调度器](https://blog.csdn.net/jiejiemcu/article/details/99665883)
|
||||
|
||||
- [【TencentOS tiny 学习】源码分析(3)——队列](https://blog.csdn.net/jiejiemcu/article/details/99687678)
|
||||
|
||||
- [【TencentOS tiny 学习】源码分析(4)——消息队列](https://blog.csdn.net/jiejiemcu/article/details/99781093)
|
||||
|
||||
- [【TencentOS tiny 学习】源码分析(5)——信号量](https://blog.csdn.net/jiejiemcu/article/details/100052643)
|
||||
|
||||
- [【TencentOS tiny 学习】源码分析(6)——互斥锁](https://blog.csdn.net/jiejiemcu/article/details/100056641)
|
||||
|
||||
- [【TencentOS tiny 学习】源码分析(7)——事件](https://blog.csdn.net/jiejiemcu/article/details/100492219)
|
||||
|
||||
- [【TencentOS tiny 学习】源码分析(8)——软件定时器](https://blog.csdn.net/jiejiemcu/article/details/101846089)
|
||||
|
||||
## 配套例程:
|
||||
|
||||
- [【TencentOS tiny 学习】例程(0)——hello world](https://github.com/jiejieTop/TencentOS-Demo/tree/master/hello-world)
|
||||
|
||||
- [【TencentOS tiny 学习】例程(1)——task](https://github.com/jiejieTop/TencentOS-Demo/tree/master/01-task)
|
||||
|
||||
- [【TencentOS tiny 学习】例程(2)——队列](https://github.com/jiejieTop/TencentOS-Demo/tree/master/02-queue)
|
||||
|
||||
- [【TencentOS tiny 学习】例程(3)——消息队列](https://github.com/jiejieTop/TencentOS-Demo/tree/master/03-msg_queue)
|
||||
|
||||
- [【TencentOS tiny 学习】例程(4)——信号量](https://github.com/jiejieTop/TencentOS-Demo/tree/master/04-sem)
|
||||
|
||||
- [【TencentOS tiny 学习】例程(5)——互斥锁](https://github.com/jiejieTop/TencentOS-Demo/tree/master/05-mutex)
|
||||
|
||||
- [【TencentOS tiny 学习】例程(6)——事件](https://github.com/jiejieTop/TencentOS-Demo/tree/master/06-event)
|
||||
|
||||
- [【TencentOS tiny 学习】例程(7)——软件定时器](https://github.com/jiejieTop/TencentOS-Demo/tree/master/07-timer)
|
||||
|
||||
- [【TencentOS tiny 学习】例程(8)——内存池](https://github.com/jiejieTop/TencentOS-Demo/tree/master/08-mmblk)
|
||||
|
||||
- [【TencentOS tiny 学习】例程(9)——内存堆](https://github.com/jiejieTop/TencentOS-Demo/tree/master/09-mmheap)
|
||||
|
||||
|
||||
## 视频教程:
|
||||
|
||||
- [【TencentOS tiny 学习】视频汇总](https://www.bilibili.com/video/av70478596?from=search&seid=10160676184801585522)
|
||||
- [【视频】01-初识 TencentOS tiny](https://www.bilibili.com/video/av70478596/?p=1)
|
||||
- [【视频】02-TencentOS tiny 基础知识](https://www.bilibili.com/video/av70478596/?p=2)
|
||||
- [【视频】03-TencentOS tiny 移植](https://www.bilibili.com/video/av70478596/?p=3)
|
||||
- [【视频】04-TencentOS tiny 任务-1](https://www.bilibili.com/video/av70478596/?p=4)
|
||||
- [【视频】05-TencentOS tiny 任务-2](https://www.bilibili.com/video/av70478596/?p=5)
|
||||
- [【视频】06-TencentOS tiny 队列-1](https://www.bilibili.com/video/av70478596/?p=6)
|
||||
- [【视频】07-TencentOS tiny 队列-2](https://www.bilibili.com/video/av70478596/?p=7)
|
||||
- [【视频】08-TencentOS tiny 消息队列](https://www.bilibili.com/video/av70478596/?p=8)
|
||||
- [【视频】09-TencentOS tiny 信号量-1](https://www.bilibili.com/video/av70478596/?p=9)
|
||||
- [【视频】10-TencentOS tiny 信号量-2](https://www.bilibili.com/video/av70478596/?p=10)
|
||||
- [【视频】11-TencentOS tiny 互斥锁-1](https://www.bilibili.com/video/av70478596/?p=11)
|
||||
- [【视频】12-TencentOS tiny 互斥锁-2](https://www.bilibili.com/video/av70478596/?p=12)
|
||||
- [【视频】13-TencentOS tiny 互斥锁-3](https://www.bilibili.com/video/av70478596/?p=13)
|
||||
- [【视频】14-TencentOS tiny 事件-1](https://www.bilibili.com/video/av70478596/?p=14)
|
||||
- [【视频】15-TencentOS tiny 事件-2](https://www.bilibili.com/video/av70478596/?p=15)
|
||||
- [【视频】16-TencentOS tiny 软件定时器-1](https://www.bilibili.com/video/av70478596/?p=16)
|
||||
- [【视频】17-TencentOS tiny 软件定时器-2](https://www.bilibili.com/video/av70478596/?p=11)
|
||||
- [【视频】18-TencentOS tiny 软件定时器-3](https://www.bilibili.com/video/av70478596/?p=18)
|
||||
|
||||
## 相关PPT资料:
|
||||
- [【TencentOS tiny 学习】视频 PPT](https://github.com/jiejieTop/TencentOS-Demo/tree/master/PPT)
|
||||
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
|
||||

|
||||
|
||||
[](https://github.com/Tencent/TencentOS-tiny/blob/master/LICENSE)
|
||||
[](https://github.com/Tencent/TencentOS-tiny/pulls)
|
||||
[](https://travis-ci.org/Tencent/TencentOS-tiny)
|
||||
|
||||
[(中文)](README.md)
|
||||
|
||||
# Introduction to TencentOS Tiny
|
||||
|
||||
[TencentOS tiny](https://cloud.tencent.com/product/tos-tiny) is a real-time operating system developed by Tencent for the Internet of Things. It features low power consumption, low resource consumption, modularity, security and reliability, and can effectively improve the development efficiency of IoT terminal products. TencentOS tiny provides a streamlined RTOS core that can be tailored and configurable for rapid migration to a wide range of mainstream MCUs (such as the full range of STM32) and module chips. Moreover, based on the RTOS kernel, it provides a wealth of IoT components, and internally integrates mainstream IoT protocol stacks (such as CoAP/MQTT/TLS/DTLS/LoRaWAN/NB-IoT, etc.), which can help IoT terminals and services to quickly access Tencent. Cloud Internet of Things platform.
|
||||
|
||||
|
||||
## 1、The software architecture of TencentOS tiny
|
||||
|
||||

|
||||
|
||||
TencentOS tiny main architecture diagram, from bottom to top, mainly includes:
|
||||
|
||||
**CPU libs** :The CPU IP core architecture supported by TencentOS tiny,currently supports ARM Cortex M0/3/4/7.
|
||||
|
||||
**Drive management** :Including board support package (BSP, mainly developed and maintained by MCU chip manufacturers), hardware abstraction layer (HAL, mainly provided by TencentOS tiny, to facilitate adaptation and porting of different chips), device drivers (Drivers, such as Wi-Fi, GPRS Drivers for modules such as LoRa).
|
||||
|
||||
**kernel** :The TencentOS tiny real-time kernel includes tasks management, real-time scheduling, time management, interrupt management, memory management, exception handling, software timers, linked lists, message queues, semaphores, mutex locks, event flags, and more.
|
||||
|
||||
**IoT protocol stack**:TencentOS tiny provides lwip, AT Adapter, SAL layer, supports different network hardware, such as Ethernet, serial Wi-Fi, GPRS, NB-IoT, 4G and other communication modules. A commonly used IoT protocol stack, such as CoAP and MQTT, is provided on the TCP/IP network protocol stack to support the terminal service to quickly access Tencent Cloud.
|
||||
|
||||
**Security framework**:TencentOS tiny provides a complete security solution to ensure data transmission security and device authentication security for IoT terminals. The DTLS and TLS security protocols provided by the security framework reinforce the transport layer of COAP and MQTT to ensure that the IoT terminal implements secure authentication and data encryption when docking Tencent Cloud. In addition, for the low-resource terminal hardware, the security framework also provides Tencent. The key authentication scheme of the cloud IoTHub ensures that resource-constrained devices can also achieve device security certification to a certain extent.
|
||||
|
||||
**Component framework**:TencentOS tiny provides a series of components such as file system, KV storage, ad hoc network, JS engine, low-power framework, device framework, OTA, and debugging toolchain for users to choose according to business scenarios.
|
||||
|
||||
**Open API (in planning and development)**:TencentOS tiny will provide open API functions on the protocol middleware and framework layer, which is convenient for users to call the middleware function, so that users do not need to pay much attention to the implementation of middleware, quickly connect to Tencent cloud, realize the cloud demand on the terminal business, and expect the maximum degree. Reduce the development cycle of the terminal IoT product and save development costs.
|
||||
|
||||
**examples**:TencentOS tiny provides sample code, module test code, etc., which is convenient for users to refer to.
|
||||
|
||||
## 2、Key features of TencentOS tiny
|
||||
|
||||
### (1).Small size
|
||||
|
||||
Minimum kernel: RAM 0.6KB, ROM 1.8KB;
|
||||
|
||||
Typical LoraWAN and Sensor Applications: RAM 3.3KB, ROM 12KB.
|
||||
|
||||
### (2).Low power consumption
|
||||
|
||||
Minimum sleep power consumption as low as 2 uA;
|
||||
|
||||
Support for peripheral power management framework;
|
||||
|
||||
### (3).Rich IoT components
|
||||
|
||||
Integrate mainstream IoT protocol stack;
|
||||
|
||||
Multiple communication module SAL layer adaptation framework;
|
||||
|
||||
Support FOTA;
|
||||
|
||||
Provides easy-to-use end-cloud API to accelerate user service access to Tencent Cloud.
|
||||
|
||||
### (4).Reliable security framework
|
||||
|
||||
Diversified security grading scheme;
|
||||
|
||||
Balanced security requirements & cost control.
|
||||
|
||||
### (5).Good portability
|
||||
|
||||
Highly decoupled core and IoT components, providing a standard adaptation layer;
|
||||
|
||||
Provide automated migration tools to improve development efficiency.
|
||||
|
||||
### (6).Convenient debugging means
|
||||
Provide cloudized last screen debugging;
|
||||
|
||||
The fault scene information is automatically uploaded to the cloud platform, which is convenient for developers to debug and analyze.
|
||||
|
||||
## 3、TencentOS tiny and partners are committed to building the IoT ecosystem
|
||||
|
||||

|
||||
|
||||
TencentOS tiny currently supports mainstream MCUs such as STM32, NXP, Huada Semiconductor, National Technology, GD32, Nordic, and TI. Two sets of official custom development board designs have been completed, supporting the full range of STM32 NUCLEO official evaluation board kernel migration. TencentOS tiny will work together with partners to provide better IoT terminal software solutions for IoT terminal manufacturers, facilitating the rapid access of various IoT devices to Tencent Cloud, and jointly expanding the IoT ecosystem to better support smart cities, smart water meters, and smart homes. , smart wear, car networking and other industrial applications.
|
||||
|
||||
# TencentOS tiny code directory
|
||||
- [TencentOS tiny code directory description](./doc/09.Code_Directories.md)
|
||||
|
||||
# TencentOS tiny reference documentation
|
||||
## 1、Porting guide
|
||||
- [TencentOS tiny Porting guide(KEIL version)](./doc/10.Porting_Manual_for_KEIL.md)
|
||||
- [TencentOS tiny Porting guide(IAR version)](./doc/11.Porting_Manual_for_IAR.md)
|
||||
- [TencentOS tiny Porting guide(GCC version)](./doc/12.Porting_Manual_for_GCC.md)
|
||||
|
||||
## 2、Development guide
|
||||
- [TencentOS tiny Kernel development guide](./doc/04.Development_Manual.md)
|
||||
- [TencentOS tiny API reference](./doc/05.SDK_Manual.md)
|
||||
- [The development Guide for use TencentOS tiny connect to Tencent Cloud IoTHub ](./doc/08.QCloud_IoTHub_Quick_Start.md)
|
||||
|
||||
# TencentOS tiny opensource license
|
||||
* TencentOS tiny follow [BSD-3 Open source license agreement](LICENSE)
|
||||
|
||||
|
||||
# The IoT platform TencentOS tiny support
|
||||
TencentOS tiny can support IoT terminal devices and services for fast access to Tencent Cloud IoT Platform [IoT Explorer](https://cloud.tencent.com/product/iotexplorer)。
|
||||
|
||||
TencentOS tiny combines Tencent Cloud IoT development platform IoT Explorer, which has built up the ability to connect communication chips to cloud development. Together with the largest LoRa network in China, Tencent has completely opened up from chip communication development, network support services, and physical equipment. Defining management, data analysis and multi-scenario application development and other full-chain IoT cloud development service capabilities, redefining the IoT development model, helping multi-mode low threshold access to Tencent cloud services. As an IoT infrastructure construction service provider, Tencent will continue to build an open IoT ecosystem and promote the sound development of the Internet of Things.
|
||||
|
||||
# TencentOS tiny Quick Start Reference
|
||||
TencentOS tiny joint partner (Nanjing Houde IoT) designed a custom development board, as shown below:
|
||||

|
||||
|
||||
- [TencentOS tiny custom development board introduction page](http://www.holdiot.com/product/showproduct.php?id=8) ,Developers can quickly learn based on custom development boards, click to download reference documentation
|
||||
- [TencentOS-tiny Custom Development Board Getting Started Guide](./doc/15.TencentOS_tiny_EVB_MX_Plus_Quick_Start.md)
|
||||
|
||||
# Contributing
|
||||
* 1. Fork TencentOS tiny open source project under your own GitHub account;
|
||||
* 2. Clone a TencentOS tiny code locally according to your needs;
|
||||
* 3. After you modify or add a new function, push to the remote branch of your fork;
|
||||
* 4. Create a pull request and submit a join request to the official TencentOS tiny development branch;
|
||||
* 5. The TencentOS tiny R&D team will periodically review the code and merge your pull request.
|
||||
|
||||
# Join the TencentOS tiny official QQ technology exchange group
|
||||
|
||||
Scan the QR code to join the qq group, please note the TencentOS tiny developer, the TencentOS tiny staff will review according to the notes:
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
|
@ -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_ */
|
||||
|
||||
|
|
@ -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_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");
|
||||
}
|
||||
|
||||
__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,311 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* 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.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016-2018 Armink (armink.ztl@gmail.com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* 'Software'), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _PORT_H_
|
||||
#define _PORT_H_
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
typedef struct port_fault_regs {
|
||||
union {
|
||||
/* System Handler Control and State Register (0xE000ED24) */
|
||||
uint32_t value;
|
||||
struct {
|
||||
/* Read as 1 if memory management fault is active */
|
||||
uint32_t MEMFAULTACT : 1;
|
||||
/* Read as 1 if bus fault exception is active */
|
||||
uint32_t BUSFAULTACT : 1;
|
||||
uint32_t UnusedBits1 : 1;
|
||||
/* Read as 1 if usage fault exception is active */
|
||||
uint32_t USGFAULTACT : 1;
|
||||
uint32_t UnusedBits2 : 3;
|
||||
/* Read as 1 if SVC exception is active */
|
||||
uint32_t SVCALLACT : 1;
|
||||
/* Read as 1 if debug monitor exception is active */
|
||||
uint32_t MONITORACT : 1;
|
||||
uint32_t UnusedBits3 : 1;
|
||||
/* Read as 1 if PendSV exception is active */
|
||||
uint32_t PENDSVACT : 1;
|
||||
/* Read as 1 if SYSTICK exception is active */
|
||||
uint32_t SYSTICKACT : 1;
|
||||
/* Usage fault pended; usage fault started but was replaced by a higher-priority exception */
|
||||
uint32_t USGFAULTPENDED : 1;
|
||||
/* Memory management fault pended; memory management fault started but was replaced by a
|
||||
higher-priority exception */
|
||||
uint32_t MEMFAULTPENDED : 1;
|
||||
/* Bus fault pended; bus fault handler was started but was replaced by a higher-priority
|
||||
exception */
|
||||
uint32_t BUSFAULTPENDED : 1;
|
||||
/* SVC pended; SVC was started but was replaced by a higher-priority exception */
|
||||
uint32_t SVCALLPENDED : 1;
|
||||
/* Memory management fault handler enable */
|
||||
uint32_t MEMFAULTENA : 1;
|
||||
/* Bus fault handler enable */
|
||||
uint32_t BUSFAULTENA : 1;
|
||||
/* Usage fault handler enable */
|
||||
uint32_t USGFAULTENA : 1;
|
||||
} bits;
|
||||
} syshndctrl;
|
||||
|
||||
union {
|
||||
uint32_t value;
|
||||
|
||||
struct {
|
||||
union {
|
||||
/* Memory Management Fault Status Register (0xE000ED28) */
|
||||
uint8_t value;
|
||||
struct {
|
||||
/* Instruction access violation */
|
||||
uint8_t IACCVIOL : 1;
|
||||
/* Data access violation */
|
||||
uint8_t DACCVIOL : 1;
|
||||
uint8_t UnusedBits : 1;
|
||||
/* Unstacking error */
|
||||
uint8_t MUNSTKERR : 1;
|
||||
/* Stacking error */
|
||||
uint8_t MSTKERR : 1;
|
||||
/* Floating-point lazy state preservation (M4/M7) */
|
||||
uint8_t MLSPERR : 1;
|
||||
uint8_t UnusedBits2 : 1;
|
||||
/* Indicates the MMAR is valid */
|
||||
uint8_t MMARVALID : 1;
|
||||
} bits;
|
||||
} mfsr;
|
||||
|
||||
union {
|
||||
/* Bus Fault Status Register (0xE000ED29) */
|
||||
uint8_t value;
|
||||
struct {
|
||||
/* Instruction access violation */
|
||||
uint8_t IBUSERR : 1;
|
||||
/* Precise data access violation */
|
||||
uint8_t PRECISERR : 1;
|
||||
/* Imprecise data access violation */
|
||||
uint8_t IMPREISERR : 1;
|
||||
/* Unstacking error */
|
||||
uint8_t UNSTKERR : 1;
|
||||
/* Stacking error */
|
||||
uint8_t STKERR : 1;
|
||||
/* Floating-point lazy state preservation (M4/M7) */
|
||||
uint8_t LSPERR : 1;
|
||||
uint8_t UnusedBits : 1;
|
||||
/* Indicates BFAR is valid */
|
||||
uint8_t BFARVALID : 1;
|
||||
} bits;
|
||||
} bfsr;
|
||||
|
||||
union {
|
||||
/* Usage Fault Status Register (0xE000ED2A) */
|
||||
uint16_t value;
|
||||
struct {
|
||||
/* Attempts to execute an undefined instruction */
|
||||
uint16_t UNDEFINSTR : 1;
|
||||
/* Attempts to switch to an invalid state (e.g., ARM) */
|
||||
uint16_t INVSTATE : 1;
|
||||
/* Attempts to do an exception with a bad value in the EXC_RETURN number */
|
||||
uint16_t INVPC : 1;
|
||||
/* Attempts to execute a coprocessor instruction */
|
||||
uint16_t NOCP : 1;
|
||||
uint16_t UnusedBits : 4;
|
||||
/* Indicates that an unaligned access fault has taken place */
|
||||
uint16_t UNALIGNED : 1;
|
||||
/* Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set) */
|
||||
uint16_t DIVBYZERO0 : 1;
|
||||
} bits;
|
||||
} ufsr;
|
||||
} part;
|
||||
} cfsr;
|
||||
|
||||
/* Memory Management Fault Address Register (0xE000ED34) */
|
||||
uint32_t mmar;
|
||||
|
||||
/* Bus Fault Manage Address Register (0xE000ED38) */
|
||||
uint32_t bfar;
|
||||
|
||||
union {
|
||||
/* Hard Fault Status Register (0xE000ED2C) */
|
||||
uint32_t value;
|
||||
struct {
|
||||
uint32_t UnusedBits : 1;
|
||||
/* Indicates hard fault is caused by failed vector fetch */
|
||||
uint32_t VECTBL : 1;
|
||||
uint32_t UnusedBits2 : 28;
|
||||
/* Indicates hard fault is taken because of bus fault/memory management fault/usage fault */
|
||||
uint32_t FORCED : 1;
|
||||
/* Indicates hard fault is triggered by debug event */
|
||||
uint32_t DEBUGEVT : 1;
|
||||
} bits;
|
||||
} hfsr;
|
||||
|
||||
union {
|
||||
/* Debug Fault Status Register (0xE000ED30) */
|
||||
uint32_t value;
|
||||
struct {
|
||||
/* Halt requested in NVIC */
|
||||
uint32_t HALTED : 1;
|
||||
/* BKPT instruction executed */
|
||||
uint32_t BKPT : 1;
|
||||
/* DWT match occurred */
|
||||
uint32_t DWTTRAP : 1;
|
||||
/* Vector fetch occurred */
|
||||
uint32_t VCATCH : 1;
|
||||
/* EDBGRQ signal asserted */
|
||||
uint32_t EXTERNAL : 1;
|
||||
} bits;
|
||||
} dfsr;
|
||||
|
||||
/* Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional) */
|
||||
uint32_t afsr;
|
||||
} port_fault_regs_t;
|
||||
|
||||
enum fault_info {
|
||||
FAULT_INFO_ASSERT_ON_THREAD,
|
||||
FAULT_INFO_HFSR_VECTBL,
|
||||
FAULT_INFO_MFSR_IACCVIOL,
|
||||
FAULT_INFO_MFSR_DACCVIOL,
|
||||
FAULT_INFO_MFSR_MUNSTKERR,
|
||||
FAULT_INFO_MFSR_MSTKERR,
|
||||
FAULT_INFO_MFSR_MLSPERR,
|
||||
FAULT_INFO_BFSR_IBUSERR,
|
||||
FAULT_INFO_BFSR_PRECISERR,
|
||||
FAULT_INFO_BFSR_IMPREISERR,
|
||||
FAULT_INFO_BFSR_UNSTKERR,
|
||||
FAULT_INFO_BFSR_STKERR,
|
||||
FAULT_INFO_BFSR_LSPERR,
|
||||
FAULT_INFO_UFSR_UNDEFINSTR,
|
||||
FAULT_INFO_UFSR_INVSTATE,
|
||||
FAULT_INFO_UFSR_INVPC,
|
||||
FAULT_INFO_UFSR_NOCP,
|
||||
FAULT_INFO_UFSR_UNALIGNED,
|
||||
FAULT_INFO_UFSR_DIVBYZERO0,
|
||||
FAULT_INFO_DFSR_HALTED,
|
||||
FAULT_INFO_DFSR_BKPT,
|
||||
FAULT_INFO_DFSR_DWTTRAP,
|
||||
FAULT_INFO_DFSR_VCATCH,
|
||||
FAULT_INFO_DFSR_EXTERNAL,
|
||||
FAULT_INFO_MMAR,
|
||||
FAULT_INFO_BFAR,
|
||||
};
|
||||
|
||||
static const char *const fault_msg[] = {
|
||||
[FAULT_INFO_ASSERT_ON_THREAD] = "Assert on thread %s\n",
|
||||
[FAULT_INFO_HFSR_VECTBL] = "Hard fault is caused by failed vector fetch\n",
|
||||
[FAULT_INFO_MFSR_IACCVIOL] = "Memory management fault: instruction access violation\n",
|
||||
[FAULT_INFO_MFSR_DACCVIOL] = "Memory management fault: data access violation\n",
|
||||
[FAULT_INFO_MFSR_MUNSTKERR] = "Memory management fault: unstacking error\n",
|
||||
[FAULT_INFO_MFSR_MSTKERR] = "Memory management fault: stacking error\n",
|
||||
[FAULT_INFO_MFSR_MLSPERR] = "Memory management fault: floating-point lazy state preservation\n",
|
||||
[FAULT_INFO_BFSR_IBUSERR] = "Bus fault: instruction access violation\n",
|
||||
[FAULT_INFO_BFSR_PRECISERR] = "Bus fault: precise data access violation\n",
|
||||
[FAULT_INFO_BFSR_IMPREISERR] = "Bus fault: imprecise data access violation\n",
|
||||
[FAULT_INFO_BFSR_UNSTKERR] = "Bus fault: unstacking error\n",
|
||||
[FAULT_INFO_BFSR_STKERR] = "Bus fault: stacking error\n",
|
||||
[FAULT_INFO_BFSR_LSPERR] = "Bus fault: floating-point lazy state preservation\n",
|
||||
[FAULT_INFO_UFSR_UNDEFINSTR] = "Usage fault: undefined instruction\n",
|
||||
[FAULT_INFO_UFSR_INVSTATE] = "Usage fault: invalid state (e.g., ARM)\n",
|
||||
[FAULT_INFO_UFSR_INVPC] = "Usage fault: invalid EXC_RETURN\n",
|
||||
[FAULT_INFO_UFSR_NOCP] = "Usage fault: coprocessor instruction\n",
|
||||
[FAULT_INFO_UFSR_UNALIGNED] = "Usage fault: unaligned access\n",
|
||||
[FAULT_INFO_UFSR_DIVBYZERO0] = "Usage fault: divide by zero(can be set only if DIV_0_TRP is set)\n",
|
||||
[FAULT_INFO_DFSR_HALTED] = "Debug fault: halt requested in NVIC\n",
|
||||
[FAULT_INFO_DFSR_BKPT] = "Debug fault: BKPT instruction executed\n",
|
||||
[FAULT_INFO_DFSR_DWTTRAP] = "Debug fault: DWT match occurred\n",
|
||||
[FAULT_INFO_DFSR_VCATCH] = "Debug fault: Vector fetch occurred\n",
|
||||
[FAULT_INFO_DFSR_EXTERNAL] = "Debug fault: EDBGRQ signal asserted\n",
|
||||
[FAULT_INFO_MMAR] = "The memory management fault occurred address is %08x\n",
|
||||
[FAULT_INFO_BFAR] = "The bus fault occurred address is %08x\n",
|
||||
};
|
||||
|
||||
__PORT__ void HardFault_Handler(void);
|
||||
|
||||
__PORT__ void port_fault_diagnosis(void);
|
||||
#endif
|
||||
|
||||
#if defined(TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT) && (TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT == 1u)
|
||||
__PORT__ uint32_t port_clz(uint32_t val);
|
||||
#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,276 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* 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.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016-2018 Armink (armink.ztl@gmail.com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* 'Software'), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "tos_k.h"
|
||||
#include "core_cm3.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
|
||||
__STATIC__ void port_fault_do_diagnosis(port_fault_regs_t *regs)
|
||||
{
|
||||
k_fault_log_writer("\n\n====================== Fault Diagnosis =====================\n");
|
||||
|
||||
if (regs->hfsr.bits.VECTBL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_HFSR_VECTBL]);
|
||||
}
|
||||
if (regs->hfsr.bits.FORCED) {
|
||||
/* Memory Management Fault */
|
||||
if (regs->cfsr.part.mfsr.value) {
|
||||
if (regs->cfsr.part.mfsr.bits.IACCVIOL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_IACCVIOL]);
|
||||
}
|
||||
if (regs->cfsr.part.mfsr.bits.DACCVIOL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_DACCVIOL]);
|
||||
}
|
||||
if (regs->cfsr.part.mfsr.bits.MUNSTKERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MUNSTKERR]);
|
||||
}
|
||||
if (regs->cfsr.part.mfsr.bits.MSTKERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MSTKERR]);
|
||||
}
|
||||
|
||||
if (regs->cfsr.part.mfsr.bits.MLSPERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MLSPERR]);
|
||||
}
|
||||
|
||||
if (regs->cfsr.part.mfsr.bits.MMARVALID) {
|
||||
if (regs->cfsr.part.mfsr.bits.IACCVIOL || regs->cfsr.part.mfsr.bits.DACCVIOL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MMAR], regs->mmar);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Bus Fault */
|
||||
if (regs->cfsr.part.bfsr.value) {
|
||||
if (regs->cfsr.part.bfsr.bits.IBUSERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_IBUSERR]);
|
||||
}
|
||||
if (regs->cfsr.part.bfsr.bits.PRECISERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_PRECISERR]);
|
||||
}
|
||||
if (regs->cfsr.part.bfsr.bits.IMPREISERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_IMPREISERR]);
|
||||
}
|
||||
if (regs->cfsr.part.bfsr.bits.UNSTKERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_UNSTKERR]);
|
||||
}
|
||||
if (regs->cfsr.part.bfsr.bits.STKERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_STKERR]);
|
||||
}
|
||||
|
||||
if (regs->cfsr.part.bfsr.bits.LSPERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_LSPERR]);
|
||||
}
|
||||
|
||||
if (regs->cfsr.part.bfsr.bits.BFARVALID) {
|
||||
if (regs->cfsr.part.bfsr.bits.PRECISERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFAR], regs->bfar);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* Usage Fault */
|
||||
if (regs->cfsr.part.ufsr.value) {
|
||||
if (regs->cfsr.part.ufsr.bits.UNDEFINSTR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_UNDEFINSTR]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.INVSTATE) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_INVSTATE]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.INVPC) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_INVPC]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.NOCP) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_NOCP]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.UNALIGNED) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_UNALIGNED]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.DIVBYZERO0) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_DIVBYZERO0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Debug Fault */
|
||||
if (regs->hfsr.bits.DEBUGEVT) {
|
||||
if (regs->dfsr.value) {
|
||||
if (regs->dfsr.bits.HALTED) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_HALTED]);
|
||||
}
|
||||
if (regs->dfsr.bits.BKPT) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_BKPT]);
|
||||
}
|
||||
if (regs->dfsr.bits.DWTTRAP) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_DWTTRAP]);
|
||||
}
|
||||
if (regs->dfsr.bits.VCATCH) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_VCATCH]);
|
||||
}
|
||||
if (regs->dfsr.bits.EXTERNAL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_EXTERNAL]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__PORT__ void port_fault_diagnosis(void)
|
||||
{
|
||||
port_fault_regs_t regs;
|
||||
|
||||
regs.syshndctrl.value = SCB->SHCSR;
|
||||
regs.cfsr.value = SCB->CFSR;
|
||||
regs.mmar = SCB->MMFAR;
|
||||
regs.bfar = SCB->BFAR;
|
||||
regs.hfsr.value = SCB->HFSR;
|
||||
regs.dfsr.value = SCB->DFSR;
|
||||
regs.afsr = SCB->AFSR;
|
||||
|
||||
port_fault_do_diagnosis(®s);
|
||||
}
|
||||
|
||||
/*------------------ 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 1u
|
||||
#define TOS_CFG_CPU_BYTE_ORDER CPU_BYTE_ORDER_LITTLE_ENDIAN
|
||||
|
||||
#endif /* _PORT_CONFIG_H_ */
|
||||
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
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 port_clz
|
||||
|
||||
EXPORT PendSV_Handler
|
||||
|
||||
IMPORT k_curr_task
|
||||
IMPORT k_next_task
|
||||
|
||||
|
||||
NVIC_INT_CTRL EQU 0xE000ED04
|
||||
NVIC_SYSPRI14 EQU 0xE000ED22
|
||||
NVIC_PENDSV_PRI EQU 0xFF
|
||||
NVIC_PENDSVSET EQU 0x10000000
|
||||
|
||||
|
||||
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_clz
|
||||
port_clz
|
||||
CLZ R0, R0
|
||||
BX LR
|
||||
|
||||
|
||||
GLOBAL port_sched_start
|
||||
port_sched_start
|
||||
LDR R0, =NVIC_SYSPRI14
|
||||
LDR R1, =NVIC_PENDSV_PRI
|
||||
STRB 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
|
||||
CBZ R0, PendSVHandler_nosave
|
||||
|
||||
SUBS R0, R0, #0x20
|
||||
STM R0, {R4 - R11}
|
||||
|
||||
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]
|
||||
LDM R0, {R4 - R11}
|
||||
ADDS R0, R0, #0x20
|
||||
MSR PSP, R0
|
||||
ORR LR, LR, #0x04
|
||||
CPSIE I
|
||||
BX LR
|
||||
NOP
|
||||
END
|
||||
|
||||
|
|
@ -0,0 +1,311 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* 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.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016-2018 Armink (armink.ztl@gmail.com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* 'Software'), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _PORT_H_
|
||||
#define _PORT_H_
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
typedef struct port_fault_regs {
|
||||
union {
|
||||
/* System Handler Control and State Register (0xE000ED24) */
|
||||
uint32_t value;
|
||||
struct {
|
||||
/* Read as 1 if memory management fault is active */
|
||||
uint32_t MEMFAULTACT : 1;
|
||||
/* Read as 1 if bus fault exception is active */
|
||||
uint32_t BUSFAULTACT : 1;
|
||||
uint32_t UnusedBits1 : 1;
|
||||
/* Read as 1 if usage fault exception is active */
|
||||
uint32_t USGFAULTACT : 1;
|
||||
uint32_t UnusedBits2 : 3;
|
||||
/* Read as 1 if SVC exception is active */
|
||||
uint32_t SVCALLACT : 1;
|
||||
/* Read as 1 if debug monitor exception is active */
|
||||
uint32_t MONITORACT : 1;
|
||||
uint32_t UnusedBits3 : 1;
|
||||
/* Read as 1 if PendSV exception is active */
|
||||
uint32_t PENDSVACT : 1;
|
||||
/* Read as 1 if SYSTICK exception is active */
|
||||
uint32_t SYSTICKACT : 1;
|
||||
/* Usage fault pended; usage fault started but was replaced by a higher-priority exception */
|
||||
uint32_t USGFAULTPENDED : 1;
|
||||
/* Memory management fault pended; memory management fault started but was replaced by a
|
||||
higher-priority exception */
|
||||
uint32_t MEMFAULTPENDED : 1;
|
||||
/* Bus fault pended; bus fault handler was started but was replaced by a higher-priority
|
||||
exception */
|
||||
uint32_t BUSFAULTPENDED : 1;
|
||||
/* SVC pended; SVC was started but was replaced by a higher-priority exception */
|
||||
uint32_t SVCALLPENDED : 1;
|
||||
/* Memory management fault handler enable */
|
||||
uint32_t MEMFAULTENA : 1;
|
||||
/* Bus fault handler enable */
|
||||
uint32_t BUSFAULTENA : 1;
|
||||
/* Usage fault handler enable */
|
||||
uint32_t USGFAULTENA : 1;
|
||||
} bits;
|
||||
} syshndctrl;
|
||||
|
||||
union {
|
||||
uint32_t value;
|
||||
|
||||
struct {
|
||||
union {
|
||||
/* Memory Management Fault Status Register (0xE000ED28) */
|
||||
uint8_t value;
|
||||
struct {
|
||||
/* Instruction access violation */
|
||||
uint8_t IACCVIOL : 1;
|
||||
/* Data access violation */
|
||||
uint8_t DACCVIOL : 1;
|
||||
uint8_t UnusedBits : 1;
|
||||
/* Unstacking error */
|
||||
uint8_t MUNSTKERR : 1;
|
||||
/* Stacking error */
|
||||
uint8_t MSTKERR : 1;
|
||||
/* Floating-point lazy state preservation (M4/M7) */
|
||||
uint8_t MLSPERR : 1;
|
||||
uint8_t UnusedBits2 : 1;
|
||||
/* Indicates the MMAR is valid */
|
||||
uint8_t MMARVALID : 1;
|
||||
} bits;
|
||||
} mfsr;
|
||||
|
||||
union {
|
||||
/* Bus Fault Status Register (0xE000ED29) */
|
||||
uint8_t value;
|
||||
struct {
|
||||
/* Instruction access violation */
|
||||
uint8_t IBUSERR : 1;
|
||||
/* Precise data access violation */
|
||||
uint8_t PRECISERR : 1;
|
||||
/* Imprecise data access violation */
|
||||
uint8_t IMPREISERR : 1;
|
||||
/* Unstacking error */
|
||||
uint8_t UNSTKERR : 1;
|
||||
/* Stacking error */
|
||||
uint8_t STKERR : 1;
|
||||
/* Floating-point lazy state preservation (M4/M7) */
|
||||
uint8_t LSPERR : 1;
|
||||
uint8_t UnusedBits : 1;
|
||||
/* Indicates BFAR is valid */
|
||||
uint8_t BFARVALID : 1;
|
||||
} bits;
|
||||
} bfsr;
|
||||
|
||||
union {
|
||||
/* Usage Fault Status Register (0xE000ED2A) */
|
||||
uint16_t value;
|
||||
struct {
|
||||
/* Attempts to execute an undefined instruction */
|
||||
uint16_t UNDEFINSTR : 1;
|
||||
/* Attempts to switch to an invalid state (e.g., ARM) */
|
||||
uint16_t INVSTATE : 1;
|
||||
/* Attempts to do an exception with a bad value in the EXC_RETURN number */
|
||||
uint16_t INVPC : 1;
|
||||
/* Attempts to execute a coprocessor instruction */
|
||||
uint16_t NOCP : 1;
|
||||
uint16_t UnusedBits : 4;
|
||||
/* Indicates that an unaligned access fault has taken place */
|
||||
uint16_t UNALIGNED : 1;
|
||||
/* Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set) */
|
||||
uint16_t DIVBYZERO0 : 1;
|
||||
} bits;
|
||||
} ufsr;
|
||||
} part;
|
||||
} cfsr;
|
||||
|
||||
/* Memory Management Fault Address Register (0xE000ED34) */
|
||||
uint32_t mmar;
|
||||
|
||||
/* Bus Fault Manage Address Register (0xE000ED38) */
|
||||
uint32_t bfar;
|
||||
|
||||
union {
|
||||
/* Hard Fault Status Register (0xE000ED2C) */
|
||||
uint32_t value;
|
||||
struct {
|
||||
uint32_t UnusedBits : 1;
|
||||
/* Indicates hard fault is caused by failed vector fetch */
|
||||
uint32_t VECTBL : 1;
|
||||
uint32_t UnusedBits2 : 28;
|
||||
/* Indicates hard fault is taken because of bus fault/memory management fault/usage fault */
|
||||
uint32_t FORCED : 1;
|
||||
/* Indicates hard fault is triggered by debug event */
|
||||
uint32_t DEBUGEVT : 1;
|
||||
} bits;
|
||||
} hfsr;
|
||||
|
||||
union {
|
||||
/* Debug Fault Status Register (0xE000ED30) */
|
||||
uint32_t value;
|
||||
struct {
|
||||
/* Halt requested in NVIC */
|
||||
uint32_t HALTED : 1;
|
||||
/* BKPT instruction executed */
|
||||
uint32_t BKPT : 1;
|
||||
/* DWT match occurred */
|
||||
uint32_t DWTTRAP : 1;
|
||||
/* Vector fetch occurred */
|
||||
uint32_t VCATCH : 1;
|
||||
/* EDBGRQ signal asserted */
|
||||
uint32_t EXTERNAL : 1;
|
||||
} bits;
|
||||
} dfsr;
|
||||
|
||||
/* Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional) */
|
||||
uint32_t afsr;
|
||||
} port_fault_regs_t;
|
||||
|
||||
enum fault_info {
|
||||
FAULT_INFO_ASSERT_ON_THREAD,
|
||||
FAULT_INFO_HFSR_VECTBL,
|
||||
FAULT_INFO_MFSR_IACCVIOL,
|
||||
FAULT_INFO_MFSR_DACCVIOL,
|
||||
FAULT_INFO_MFSR_MUNSTKERR,
|
||||
FAULT_INFO_MFSR_MSTKERR,
|
||||
FAULT_INFO_MFSR_MLSPERR,
|
||||
FAULT_INFO_BFSR_IBUSERR,
|
||||
FAULT_INFO_BFSR_PRECISERR,
|
||||
FAULT_INFO_BFSR_IMPREISERR,
|
||||
FAULT_INFO_BFSR_UNSTKERR,
|
||||
FAULT_INFO_BFSR_STKERR,
|
||||
FAULT_INFO_BFSR_LSPERR,
|
||||
FAULT_INFO_UFSR_UNDEFINSTR,
|
||||
FAULT_INFO_UFSR_INVSTATE,
|
||||
FAULT_INFO_UFSR_INVPC,
|
||||
FAULT_INFO_UFSR_NOCP,
|
||||
FAULT_INFO_UFSR_UNALIGNED,
|
||||
FAULT_INFO_UFSR_DIVBYZERO0,
|
||||
FAULT_INFO_DFSR_HALTED,
|
||||
FAULT_INFO_DFSR_BKPT,
|
||||
FAULT_INFO_DFSR_DWTTRAP,
|
||||
FAULT_INFO_DFSR_VCATCH,
|
||||
FAULT_INFO_DFSR_EXTERNAL,
|
||||
FAULT_INFO_MMAR,
|
||||
FAULT_INFO_BFAR,
|
||||
};
|
||||
|
||||
static const char *const fault_msg[] = {
|
||||
[FAULT_INFO_ASSERT_ON_THREAD] = "Assert on thread %s\n",
|
||||
[FAULT_INFO_HFSR_VECTBL] = "Hard fault is caused by failed vector fetch\n",
|
||||
[FAULT_INFO_MFSR_IACCVIOL] = "Memory management fault: instruction access violation\n",
|
||||
[FAULT_INFO_MFSR_DACCVIOL] = "Memory management fault: data access violation\n",
|
||||
[FAULT_INFO_MFSR_MUNSTKERR] = "Memory management fault: unstacking error\n",
|
||||
[FAULT_INFO_MFSR_MSTKERR] = "Memory management fault: stacking error\n",
|
||||
[FAULT_INFO_MFSR_MLSPERR] = "Memory management fault: floating-point lazy state preservation\n",
|
||||
[FAULT_INFO_BFSR_IBUSERR] = "Bus fault: instruction access violation\n",
|
||||
[FAULT_INFO_BFSR_PRECISERR] = "Bus fault: precise data access violation\n",
|
||||
[FAULT_INFO_BFSR_IMPREISERR] = "Bus fault: imprecise data access violation\n",
|
||||
[FAULT_INFO_BFSR_UNSTKERR] = "Bus fault: unstacking error\n",
|
||||
[FAULT_INFO_BFSR_STKERR] = "Bus fault: stacking error\n",
|
||||
[FAULT_INFO_BFSR_LSPERR] = "Bus fault: floating-point lazy state preservation\n",
|
||||
[FAULT_INFO_UFSR_UNDEFINSTR] = "Usage fault: undefined instruction\n",
|
||||
[FAULT_INFO_UFSR_INVSTATE] = "Usage fault: invalid state (e.g., ARM)\n",
|
||||
[FAULT_INFO_UFSR_INVPC] = "Usage fault: invalid EXC_RETURN\n",
|
||||
[FAULT_INFO_UFSR_NOCP] = "Usage fault: coprocessor instruction\n",
|
||||
[FAULT_INFO_UFSR_UNALIGNED] = "Usage fault: unaligned access\n",
|
||||
[FAULT_INFO_UFSR_DIVBYZERO0] = "Usage fault: divide by zero(can be set only if DIV_0_TRP is set)\n",
|
||||
[FAULT_INFO_DFSR_HALTED] = "Debug fault: halt requested in NVIC\n",
|
||||
[FAULT_INFO_DFSR_BKPT] = "Debug fault: BKPT instruction executed\n",
|
||||
[FAULT_INFO_DFSR_DWTTRAP] = "Debug fault: DWT match occurred\n",
|
||||
[FAULT_INFO_DFSR_VCATCH] = "Debug fault: Vector fetch occurred\n",
|
||||
[FAULT_INFO_DFSR_EXTERNAL] = "Debug fault: EDBGRQ signal asserted\n",
|
||||
[FAULT_INFO_MMAR] = "The memory management fault occurred address is %08x\n",
|
||||
[FAULT_INFO_BFAR] = "The bus fault occurred address is %08x\n",
|
||||
};
|
||||
|
||||
__PORT__ void HardFault_Handler(void);
|
||||
|
||||
__PORT__ void port_fault_diagnosis(void);
|
||||
#endif
|
||||
|
||||
#if defined(TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT) && (TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT == 1u)
|
||||
__PORT__ uint32_t port_clz(uint32_t val);
|
||||
#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,252 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* 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_cm3.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
|
||||
__STATIC__ void port_fault_do_diagnosis(port_fault_regs_t *regs)
|
||||
{
|
||||
k_fault_log_writer("\n\n====================== Fault Diagnosis =====================\n");
|
||||
|
||||
if (regs->hfsr.bits.VECTBL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_HFSR_VECTBL]);
|
||||
}
|
||||
if (regs->hfsr.bits.FORCED) {
|
||||
/* Memory Management Fault */
|
||||
if (regs->cfsr.part.mfsr.value) {
|
||||
if (regs->cfsr.part.mfsr.bits.IACCVIOL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_IACCVIOL]);
|
||||
}
|
||||
if (regs->cfsr.part.mfsr.bits.DACCVIOL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_DACCVIOL]);
|
||||
}
|
||||
if (regs->cfsr.part.mfsr.bits.MUNSTKERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MUNSTKERR]);
|
||||
}
|
||||
if (regs->cfsr.part.mfsr.bits.MSTKERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MSTKERR]);
|
||||
}
|
||||
|
||||
if (regs->cfsr.part.mfsr.bits.MLSPERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MLSPERR]);
|
||||
}
|
||||
|
||||
if (regs->cfsr.part.mfsr.bits.MMARVALID) {
|
||||
if (regs->cfsr.part.mfsr.bits.IACCVIOL || regs->cfsr.part.mfsr.bits.DACCVIOL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MMAR], regs->mmar);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Bus Fault */
|
||||
if (regs->cfsr.part.bfsr.value) {
|
||||
if (regs->cfsr.part.bfsr.bits.IBUSERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_IBUSERR]);
|
||||
}
|
||||
if (regs->cfsr.part.bfsr.bits.PRECISERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_PRECISERR]);
|
||||
}
|
||||
if (regs->cfsr.part.bfsr.bits.IMPREISERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_IMPREISERR]);
|
||||
}
|
||||
if (regs->cfsr.part.bfsr.bits.UNSTKERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_UNSTKERR]);
|
||||
}
|
||||
if (regs->cfsr.part.bfsr.bits.STKERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_STKERR]);
|
||||
}
|
||||
|
||||
if (regs->cfsr.part.bfsr.bits.LSPERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_LSPERR]);
|
||||
}
|
||||
|
||||
if (regs->cfsr.part.bfsr.bits.BFARVALID) {
|
||||
if (regs->cfsr.part.bfsr.bits.PRECISERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFAR], regs->bfar);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Usage Fault */
|
||||
if (regs->cfsr.part.ufsr.value) {
|
||||
if (regs->cfsr.part.ufsr.bits.UNDEFINSTR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_UNDEFINSTR]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.INVSTATE) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_INVSTATE]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.INVPC) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_INVPC]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.NOCP) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_NOCP]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.UNALIGNED) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_UNALIGNED]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.DIVBYZERO0) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_DIVBYZERO0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Debug Fault */
|
||||
if (regs->hfsr.bits.DEBUGEVT) {
|
||||
if (regs->dfsr.value) {
|
||||
if (regs->dfsr.bits.HALTED) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_HALTED]);
|
||||
}
|
||||
if (regs->dfsr.bits.BKPT) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_BKPT]);
|
||||
}
|
||||
if (regs->dfsr.bits.DWTTRAP) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_DWTTRAP]);
|
||||
}
|
||||
if (regs->dfsr.bits.VCATCH) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_VCATCH]);
|
||||
}
|
||||
if (regs->dfsr.bits.EXTERNAL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_EXTERNAL]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC__ void port_fault_do_diagnosis(port_fault_regs_t *regs)
|
||||
{
|
||||
port_fault_regs_t regs;
|
||||
|
||||
regs.syshndctrl.value = SCB->SHCSR;
|
||||
regs.cfsr.value = SCB->CFSR;
|
||||
regs.mmar = SCB->MMFAR;
|
||||
regs.bfar = SCB->BFAR;
|
||||
regs.hfsr.value = SCB->HFSR;
|
||||
regs.dfsr.value = SCB->DFSR;
|
||||
regs.afsr = SCB->AFSR;
|
||||
|
||||
port_fault_do_diagnosis(®s);
|
||||
}
|
||||
|
||||
/*------------------ 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 1u
|
||||
#define TOS_CFG_CPU_BYTE_ORDER CPU_BYTE_ORDER_LITTLE_ENDIAN
|
||||
|
||||
#endif /* _PORT_CONFIG_H_ */
|
||||
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
.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 port_clz
|
||||
|
||||
.global PendSV_Handler
|
||||
|
||||
.global k_curr_task
|
||||
.global k_next_task
|
||||
|
||||
|
||||
.equ NVIC_INT_CTRL , 0xE000ED04 @Interrupt control state register.
|
||||
.equ NVIC_SYSPRI14 , 0xE000ED22 @System priority register (priority 14).
|
||||
.equ NVIC_PENDSV_PRI , 0x000000FF @ 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
|
||||
|
||||
|
||||
.type port_clz, %function
|
||||
port_clz:
|
||||
CLZ R0, 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
|
||||
CBZ R0, PendSVHandler_nosave
|
||||
|
||||
SUBS R0, R0, #0x20
|
||||
STM R0, {R4 - R11}
|
||||
|
||||
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]
|
||||
LDM R0, {R4 - R11}
|
||||
ADDS R0, R0, #0x20
|
||||
MSR PSP, R0
|
||||
ORR LR, LR, #0x04
|
||||
CPSIE I
|
||||
BX LR
|
||||
NOP
|
||||
.end
|
||||
|
||||
|
|
@ -0,0 +1,312 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* 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.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016-2018 Armink (armink.ztl@gmail.com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* 'Software'), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _PORT_H_
|
||||
#define _PORT_H_
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
typedef struct port_fault_regs {
|
||||
union {
|
||||
/* System Handler Control and State Register (0xE000ED24) */
|
||||
uint32_t value;
|
||||
struct {
|
||||
/* Read as 1 if memory management fault is active */
|
||||
uint32_t MEMFAULTACT : 1;
|
||||
/* Read as 1 if bus fault exception is active */
|
||||
uint32_t BUSFAULTACT : 1;
|
||||
uint32_t UnusedBits1 : 1;
|
||||
/* Read as 1 if usage fault exception is active */
|
||||
uint32_t USGFAULTACT : 1;
|
||||
uint32_t UnusedBits2 : 3;
|
||||
/* Read as 1 if SVC exception is active */
|
||||
uint32_t SVCALLACT : 1;
|
||||
/* Read as 1 if debug monitor exception is active */
|
||||
uint32_t MONITORACT : 1;
|
||||
uint32_t UnusedBits3 : 1;
|
||||
/* Read as 1 if PendSV exception is active */
|
||||
uint32_t PENDSVACT : 1;
|
||||
/* Read as 1 if SYSTICK exception is active */
|
||||
uint32_t SYSTICKACT : 1;
|
||||
/* Usage fault pended; usage fault started but was replaced by a higher-priority exception */
|
||||
uint32_t USGFAULTPENDED : 1;
|
||||
/* Memory management fault pended; memory management fault started but was replaced by a
|
||||
higher-priority exception */
|
||||
uint32_t MEMFAULTPENDED : 1;
|
||||
/* Bus fault pended; bus fault handler was started but was replaced by a higher-priority
|
||||
exception */
|
||||
uint32_t BUSFAULTPENDED : 1;
|
||||
/* SVC pended; SVC was started but was replaced by a higher-priority exception */
|
||||
uint32_t SVCALLPENDED : 1;
|
||||
/* Memory management fault handler enable */
|
||||
uint32_t MEMFAULTENA : 1;
|
||||
/* Bus fault handler enable */
|
||||
uint32_t BUSFAULTENA : 1;
|
||||
/* Usage fault handler enable */
|
||||
uint32_t USGFAULTENA : 1;
|
||||
} bits;
|
||||
} syshndctrl;
|
||||
|
||||
union {
|
||||
uint32_t value;
|
||||
|
||||
struct {
|
||||
union {
|
||||
/* Memory Management Fault Status Register (0xE000ED28) */
|
||||
uint8_t value;
|
||||
struct {
|
||||
/* Instruction access violation */
|
||||
uint8_t IACCVIOL : 1;
|
||||
/* Data access violation */
|
||||
uint8_t DACCVIOL : 1;
|
||||
uint8_t UnusedBits : 1;
|
||||
/* Unstacking error */
|
||||
uint8_t MUNSTKERR : 1;
|
||||
/* Stacking error */
|
||||
uint8_t MSTKERR : 1;
|
||||
/* Floating-point lazy state preservation (M4/M7) */
|
||||
uint8_t MLSPERR : 1;
|
||||
uint8_t UnusedBits2 : 1;
|
||||
/* Indicates the MMAR is valid */
|
||||
uint8_t MMARVALID : 1;
|
||||
} bits;
|
||||
} mfsr;
|
||||
|
||||
union {
|
||||
/* Bus Fault Status Register (0xE000ED29) */
|
||||
uint8_t value;
|
||||
struct {
|
||||
/* Instruction access violation */
|
||||
uint8_t IBUSERR : 1;
|
||||
/* Precise data access violation */
|
||||
uint8_t PRECISERR : 1;
|
||||
/* Imprecise data access violation */
|
||||
uint8_t IMPREISERR : 1;
|
||||
/* Unstacking error */
|
||||
uint8_t UNSTKERR : 1;
|
||||
/* Stacking error */
|
||||
uint8_t STKERR : 1;
|
||||
/* Floating-point lazy state preservation (M4/M7) */
|
||||
uint8_t LSPERR : 1;
|
||||
uint8_t UnusedBits : 1;
|
||||
/* Indicates BFAR is valid */
|
||||
uint8_t BFARVALID : 1;
|
||||
} bits;
|
||||
} bfsr;
|
||||
|
||||
union {
|
||||
/* Usage Fault Status Register (0xE000ED2A) */
|
||||
uint16_t value;
|
||||
struct {
|
||||
/* Attempts to execute an undefined instruction */
|
||||
uint16_t UNDEFINSTR : 1;
|
||||
/* Attempts to switch to an invalid state (e.g., ARM) */
|
||||
uint16_t INVSTATE : 1;
|
||||
/* Attempts to do an exception with a bad value in the EXC_RETURN number */
|
||||
uint16_t INVPC : 1;
|
||||
/* Attempts to execute a coprocessor instruction */
|
||||
uint16_t NOCP : 1;
|
||||
uint16_t UnusedBits : 4;
|
||||
/* Indicates that an unaligned access fault has taken place */
|
||||
uint16_t UNALIGNED : 1;
|
||||
/* Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set) */
|
||||
uint16_t DIVBYZERO0 : 1;
|
||||
} bits;
|
||||
} ufsr;
|
||||
} part;
|
||||
} cfsr;
|
||||
|
||||
/* Memory Management Fault Address Register (0xE000ED34) */
|
||||
uint32_t mmar;
|
||||
|
||||
/* Bus Fault Manage Address Register (0xE000ED38) */
|
||||
uint32_t bfar;
|
||||
|
||||
union {
|
||||
/* Hard Fault Status Register (0xE000ED2C) */
|
||||
uint32_t value;
|
||||
struct {
|
||||
uint32_t UnusedBits : 1;
|
||||
/* Indicates hard fault is caused by failed vector fetch */
|
||||
uint32_t VECTBL : 1;
|
||||
uint32_t UnusedBits2 : 28;
|
||||
/* Indicates hard fault is taken because of bus fault/memory management fault/usage fault */
|
||||
uint32_t FORCED : 1;
|
||||
/* Indicates hard fault is triggered by debug event */
|
||||
uint32_t DEBUGEVT : 1;
|
||||
} bits;
|
||||
} hfsr;
|
||||
|
||||
union {
|
||||
/* Debug Fault Status Register (0xE000ED30) */
|
||||
uint32_t value;
|
||||
struct {
|
||||
/* Halt requested in NVIC */
|
||||
uint32_t HALTED : 1;
|
||||
/* BKPT instruction executed */
|
||||
uint32_t BKPT : 1;
|
||||
/* DWT match occurred */
|
||||
uint32_t DWTTRAP : 1;
|
||||
/* Vector fetch occurred */
|
||||
uint32_t VCATCH : 1;
|
||||
/* EDBGRQ signal asserted */
|
||||
uint32_t EXTERNAL : 1;
|
||||
} bits;
|
||||
} dfsr;
|
||||
|
||||
/* Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional) */
|
||||
uint32_t afsr;
|
||||
} port_fault_regs_t;
|
||||
|
||||
enum fault_info {
|
||||
FAULT_INFO_ASSERT_ON_THREAD,
|
||||
FAULT_INFO_HFSR_VECTBL,
|
||||
FAULT_INFO_MFSR_IACCVIOL,
|
||||
FAULT_INFO_MFSR_DACCVIOL,
|
||||
FAULT_INFO_MFSR_MUNSTKERR,
|
||||
FAULT_INFO_MFSR_MSTKERR,
|
||||
FAULT_INFO_MFSR_MLSPERR,
|
||||
FAULT_INFO_BFSR_IBUSERR,
|
||||
FAULT_INFO_BFSR_PRECISERR,
|
||||
FAULT_INFO_BFSR_IMPREISERR,
|
||||
FAULT_INFO_BFSR_UNSTKERR,
|
||||
FAULT_INFO_BFSR_STKERR,
|
||||
FAULT_INFO_BFSR_LSPERR,
|
||||
FAULT_INFO_UFSR_UNDEFINSTR,
|
||||
FAULT_INFO_UFSR_INVSTATE,
|
||||
FAULT_INFO_UFSR_INVPC,
|
||||
FAULT_INFO_UFSR_NOCP,
|
||||
FAULT_INFO_UFSR_UNALIGNED,
|
||||
FAULT_INFO_UFSR_DIVBYZERO0,
|
||||
FAULT_INFO_DFSR_HALTED,
|
||||
FAULT_INFO_DFSR_BKPT,
|
||||
FAULT_INFO_DFSR_DWTTRAP,
|
||||
FAULT_INFO_DFSR_VCATCH,
|
||||
FAULT_INFO_DFSR_EXTERNAL,
|
||||
FAULT_INFO_MMAR,
|
||||
FAULT_INFO_BFAR,
|
||||
};
|
||||
|
||||
static const char *const fault_msg[] = {
|
||||
[FAULT_INFO_ASSERT_ON_THREAD] = "Assert on thread %s\n",
|
||||
[FAULT_INFO_HFSR_VECTBL] = "Hard fault is caused by failed vector fetch\n",
|
||||
[FAULT_INFO_MFSR_IACCVIOL] = "Memory management fault: instruction access violation\n",
|
||||
[FAULT_INFO_MFSR_DACCVIOL] = "Memory management fault: data access violation\n",
|
||||
[FAULT_INFO_MFSR_MUNSTKERR] = "Memory management fault: unstacking error\n",
|
||||
[FAULT_INFO_MFSR_MSTKERR] = "Memory management fault: stacking error\n",
|
||||
[FAULT_INFO_MFSR_MLSPERR] = "Memory management fault: floating-point lazy state preservation\n",
|
||||
[FAULT_INFO_BFSR_IBUSERR] = "Bus fault: instruction access violation\n",
|
||||
[FAULT_INFO_BFSR_PRECISERR] = "Bus fault: precise data access violation\n",
|
||||
[FAULT_INFO_BFSR_IMPREISERR] = "Bus fault: imprecise data access violation\n",
|
||||
[FAULT_INFO_BFSR_UNSTKERR] = "Bus fault: unstacking error\n",
|
||||
[FAULT_INFO_BFSR_STKERR] = "Bus fault: stacking error\n",
|
||||
[FAULT_INFO_BFSR_LSPERR] = "Bus fault: floating-point lazy state preservation\n",
|
||||
[FAULT_INFO_UFSR_UNDEFINSTR] = "Usage fault: undefined instruction\n",
|
||||
[FAULT_INFO_UFSR_INVSTATE] = "Usage fault: invalid state (e.g., ARM)\n",
|
||||
[FAULT_INFO_UFSR_INVPC] = "Usage fault: invalid EXC_RETURN\n",
|
||||
[FAULT_INFO_UFSR_NOCP] = "Usage fault: coprocessor instruction\n",
|
||||
[FAULT_INFO_UFSR_UNALIGNED] = "Usage fault: unaligned access\n",
|
||||
[FAULT_INFO_UFSR_DIVBYZERO0] = "Usage fault: divide by zero(can be set only if DIV_0_TRP is set)\n",
|
||||
[FAULT_INFO_DFSR_HALTED] = "Debug fault: halt requested in NVIC\n",
|
||||
[FAULT_INFO_DFSR_BKPT] = "Debug fault: BKPT instruction executed\n",
|
||||
[FAULT_INFO_DFSR_DWTTRAP] = "Debug fault: DWT match occurred\n",
|
||||
[FAULT_INFO_DFSR_VCATCH] = "Debug fault: Vector fetch occurred\n",
|
||||
[FAULT_INFO_DFSR_EXTERNAL] = "Debug fault: EDBGRQ signal asserted\n",
|
||||
[FAULT_INFO_MMAR] = "The memory management fault occurred address is %08x\n",
|
||||
[FAULT_INFO_BFAR] = "The bus fault occurred address is %08x\n",
|
||||
};
|
||||
|
||||
__PORT__ void HardFault_Handler(void);
|
||||
|
||||
__PORT__ void port_fault_diagnosis(void);
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT) && (TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT == 1u)
|
||||
__PORT__ uint32_t port_clz(uint32_t val);
|
||||
#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,261 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* 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.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016-2018 Armink (armink.ztl@gmail.com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* 'Software'), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "tos_k.h"
|
||||
#include "core_cm3.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__ k_cycle_t port_systick_max_reload_cycle(void)
|
||||
{
|
||||
return SysTick_LOAD_RELOAD_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
|
||||
__STATIC__ void port_fault_do_diagnosis(port_fault_regs_t *regs)
|
||||
{
|
||||
k_fault_log_writer("\n\n====================== Fault Diagnosis =====================\n");
|
||||
|
||||
if (regs->hfsr.bits.VECTBL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_HFSR_VECTBL]);
|
||||
}
|
||||
if (regs->hfsr.bits.FORCED) {
|
||||
/* Memory Management Fault */
|
||||
if (regs->cfsr.part.mfsr.value) {
|
||||
if (regs->cfsr.part.mfsr.bits.IACCVIOL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_IACCVIOL]);
|
||||
}
|
||||
if (regs->cfsr.part.mfsr.bits.DACCVIOL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_DACCVIOL]);
|
||||
}
|
||||
if (regs->cfsr.part.mfsr.bits.MUNSTKERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MUNSTKERR]);
|
||||
}
|
||||
if (regs->cfsr.part.mfsr.bits.MSTKERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MSTKERR]);
|
||||
}
|
||||
|
||||
if (regs->cfsr.part.mfsr.bits.MLSPERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MLSPERR]);
|
||||
}
|
||||
|
||||
if (regs->cfsr.part.mfsr.bits.MMARVALID) {
|
||||
if (regs->cfsr.part.mfsr.bits.IACCVIOL || regs->cfsr.part.mfsr.bits.DACCVIOL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MMAR], regs->mmar);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Bus Fault */
|
||||
if (regs->cfsr.part.bfsr.value) {
|
||||
if (regs->cfsr.part.bfsr.bits.IBUSERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_IBUSERR]);
|
||||
}
|
||||
if (regs->cfsr.part.bfsr.bits.PRECISERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_PRECISERR]);
|
||||
}
|
||||
if (regs->cfsr.part.bfsr.bits.IMPREISERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_IMPREISERR]);
|
||||
}
|
||||
if (regs->cfsr.part.bfsr.bits.UNSTKERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_UNSTKERR]);
|
||||
}
|
||||
if (regs->cfsr.part.bfsr.bits.STKERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_STKERR]);
|
||||
}
|
||||
|
||||
if (regs->cfsr.part.bfsr.bits.LSPERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_LSPERR]);
|
||||
}
|
||||
|
||||
if (regs->cfsr.part.bfsr.bits.BFARVALID) {
|
||||
if (regs->cfsr.part.bfsr.bits.PRECISERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFAR], regs->bfar);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* Usage Fault */
|
||||
if (regs->cfsr.part.ufsr.value) {
|
||||
if (regs->cfsr.part.ufsr.bits.UNDEFINSTR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_UNDEFINSTR]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.INVSTATE) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_INVSTATE]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.INVPC) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_INVPC]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.NOCP) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_NOCP]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.UNALIGNED) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_UNALIGNED]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.DIVBYZERO0) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_DIVBYZERO0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Debug Fault */
|
||||
if (regs->hfsr.bits.DEBUGEVT) {
|
||||
if (regs->dfsr.value) {
|
||||
if (regs->dfsr.bits.HALTED) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_HALTED]);
|
||||
}
|
||||
if (regs->dfsr.bits.BKPT) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_BKPT]);
|
||||
}
|
||||
if (regs->dfsr.bits.DWTTRAP) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_DWTTRAP]);
|
||||
}
|
||||
if (regs->dfsr.bits.VCATCH) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_VCATCH]);
|
||||
}
|
||||
if (regs->dfsr.bits.EXTERNAL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_EXTERNAL]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__PORT__ void port_fault_diagnosis(void)
|
||||
{
|
||||
port_fault_regs_t regs;
|
||||
|
||||
regs.syshndctrl.value = SCB->SHCSR;
|
||||
regs.cfsr.value = SCB->CFSR;
|
||||
regs.mmar = SCB->MMFAR;
|
||||
regs.bfar = SCB->BFAR;
|
||||
regs.hfsr.value = SCB->HFSR;
|
||||
regs.dfsr.value = SCB->DFSR;
|
||||
regs.afsr = SCB->AFSR;
|
||||
|
||||
port_fault_do_diagnosis(®s);
|
||||
}
|
||||
|
||||
__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"
|
||||
"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 1u
|
||||
#define TOS_CFG_CPU_BYTE_ORDER CPU_BYTE_ORDER_LITTLE_ENDIAN
|
||||
|
||||
#endif /* _PORT_CONFIG_H_ */
|
||||
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
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 port_clz
|
||||
|
||||
PUBLIC PendSV_Handler
|
||||
|
||||
EXTERN k_curr_task
|
||||
EXTERN k_next_task
|
||||
|
||||
SCB_VTOR EQU 0xE000ED08
|
||||
NVIC_INT_CTRL EQU 0xE000ED04
|
||||
NVIC_SYSPRI14 EQU 0xE000ED22
|
||||
NVIC_PENDSV_PRI EQU 0xFF
|
||||
NVIC_PENDSVSET EQU 0x10000000
|
||||
|
||||
|
||||
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_clz
|
||||
CLZ R0, R0
|
||||
BX LR
|
||||
|
||||
|
||||
port_sched_start
|
||||
CPSID I
|
||||
|
||||
; set pendsv priority lowest
|
||||
; otherwise trigger pendsv in port_irq_context_switch will cause a context switch in irq
|
||||
; that would be a disaster
|
||||
MOV32 R0, NVIC_SYSPRI14
|
||||
MOV32 R1, NVIC_PENDSV_PRI
|
||||
STRB R1, [R0]
|
||||
|
||||
LDR R0, =SCB_VTOR
|
||||
LDR R0, [R0]
|
||||
LDR R0, [R0]
|
||||
MSR MSP, R0
|
||||
|
||||
; k_curr_task = k_next_task
|
||||
MOV32 R0, k_curr_task
|
||||
MOV32 R1, k_next_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
|
||||
; sp = k_next_task->sp
|
||||
LDR R0, [R2]
|
||||
; PSP = sp
|
||||
MSR PSP, R0
|
||||
|
||||
; using PSP
|
||||
MRS R0, CONTROL
|
||||
ORR R0, R0, #2
|
||||
MSR CONTROL, R0
|
||||
|
||||
ISB
|
||||
|
||||
; restore r4-11 from new process stack
|
||||
LDMFD SP!, {R4 - R11}
|
||||
|
||||
; restore r0, r3
|
||||
LDMFD SP!, {R0 - R3}
|
||||
; load R12 and LR
|
||||
LDMFD SP!, {R12, LR}
|
||||
; load PC and discard xPSR
|
||||
LDMFD SP!, {R1, R2}
|
||||
|
||||
CPSIE I
|
||||
BX R1
|
||||
|
||||
|
||||
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
|
||||
|
||||
_context_save
|
||||
; R0-R3, R12, LR, PC, xPSR is saved automatically here
|
||||
|
||||
; save remaining regs r4-11 on process stack
|
||||
STMFD R0!, {R4 - R11}
|
||||
|
||||
; k_curr_task->sp = PSP
|
||||
MOV32 R5, k_curr_task
|
||||
LDR R6, [R5]
|
||||
; R0 is SP of process being switched out
|
||||
STR R0, [R6]
|
||||
|
||||
_context_restore
|
||||
; k_curr_task = k_next_task
|
||||
MOV32 R1, k_next_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R5]
|
||||
|
||||
; R0 = k_next_task->sp
|
||||
LDR R0, [R2]
|
||||
|
||||
; restore R4 - R11
|
||||
LDMFD R0!, {R4 - R11}
|
||||
|
||||
; Load PSP with new process SP
|
||||
MSR PSP, R0
|
||||
CPSIE I
|
||||
; R0-R3, R12, LR, PC, xPSR restored automatically here
|
||||
; S0 - S16, FPSCR restored automatically here if FPCA = 1
|
||||
BX LR
|
||||
|
||||
END
|
||||
|
||||
|
|
@ -0,0 +1,312 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* 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.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016-2018 Armink (armink.ztl@gmail.com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* 'Software'), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _PORT_H_
|
||||
#define _PORT_H_
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
typedef struct port_fault_regs {
|
||||
union {
|
||||
/* System Handler Control and State Register (0xE000ED24) */
|
||||
uint32_t value;
|
||||
struct {
|
||||
/* Read as 1 if memory management fault is active */
|
||||
uint32_t MEMFAULTACT : 1;
|
||||
/* Read as 1 if bus fault exception is active */
|
||||
uint32_t BUSFAULTACT : 1;
|
||||
uint32_t UnusedBits1 : 1;
|
||||
/* Read as 1 if usage fault exception is active */
|
||||
uint32_t USGFAULTACT : 1;
|
||||
uint32_t UnusedBits2 : 3;
|
||||
/* Read as 1 if SVC exception is active */
|
||||
uint32_t SVCALLACT : 1;
|
||||
/* Read as 1 if debug monitor exception is active */
|
||||
uint32_t MONITORACT : 1;
|
||||
uint32_t UnusedBits3 : 1;
|
||||
/* Read as 1 if PendSV exception is active */
|
||||
uint32_t PENDSVACT : 1;
|
||||
/* Read as 1 if SYSTICK exception is active */
|
||||
uint32_t SYSTICKACT : 1;
|
||||
/* Usage fault pended; usage fault started but was replaced by a higher-priority exception */
|
||||
uint32_t USGFAULTPENDED : 1;
|
||||
/* Memory management fault pended; memory management fault started but was replaced by a
|
||||
higher-priority exception */
|
||||
uint32_t MEMFAULTPENDED : 1;
|
||||
/* Bus fault pended; bus fault handler was started but was replaced by a higher-priority
|
||||
exception */
|
||||
uint32_t BUSFAULTPENDED : 1;
|
||||
/* SVC pended; SVC was started but was replaced by a higher-priority exception */
|
||||
uint32_t SVCALLPENDED : 1;
|
||||
/* Memory management fault handler enable */
|
||||
uint32_t MEMFAULTENA : 1;
|
||||
/* Bus fault handler enable */
|
||||
uint32_t BUSFAULTENA : 1;
|
||||
/* Usage fault handler enable */
|
||||
uint32_t USGFAULTENA : 1;
|
||||
} bits;
|
||||
} syshndctrl;
|
||||
|
||||
union {
|
||||
uint32_t value;
|
||||
|
||||
struct {
|
||||
union {
|
||||
/* Memory Management Fault Status Register (0xE000ED28) */
|
||||
uint8_t value;
|
||||
struct {
|
||||
/* Instruction access violation */
|
||||
uint8_t IACCVIOL : 1;
|
||||
/* Data access violation */
|
||||
uint8_t DACCVIOL : 1;
|
||||
uint8_t UnusedBits : 1;
|
||||
/* Unstacking error */
|
||||
uint8_t MUNSTKERR : 1;
|
||||
/* Stacking error */
|
||||
uint8_t MSTKERR : 1;
|
||||
/* Floating-point lazy state preservation (M4/M7) */
|
||||
uint8_t MLSPERR : 1;
|
||||
uint8_t UnusedBits2 : 1;
|
||||
/* Indicates the MMAR is valid */
|
||||
uint8_t MMARVALID : 1;
|
||||
} bits;
|
||||
} mfsr;
|
||||
|
||||
union {
|
||||
/* Bus Fault Status Register (0xE000ED29) */
|
||||
uint8_t value;
|
||||
struct {
|
||||
/* Instruction access violation */
|
||||
uint8_t IBUSERR : 1;
|
||||
/* Precise data access violation */
|
||||
uint8_t PRECISERR : 1;
|
||||
/* Imprecise data access violation */
|
||||
uint8_t IMPREISERR : 1;
|
||||
/* Unstacking error */
|
||||
uint8_t UNSTKERR : 1;
|
||||
/* Stacking error */
|
||||
uint8_t STKERR : 1;
|
||||
/* Floating-point lazy state preservation (M4/M7) */
|
||||
uint8_t LSPERR : 1;
|
||||
uint8_t UnusedBits : 1;
|
||||
/* Indicates BFAR is valid */
|
||||
uint8_t BFARVALID : 1;
|
||||
} bits;
|
||||
} bfsr;
|
||||
|
||||
union {
|
||||
/* Usage Fault Status Register (0xE000ED2A) */
|
||||
uint16_t value;
|
||||
struct {
|
||||
/* Attempts to execute an undefined instruction */
|
||||
uint16_t UNDEFINSTR : 1;
|
||||
/* Attempts to switch to an invalid state (e.g., ARM) */
|
||||
uint16_t INVSTATE : 1;
|
||||
/* Attempts to do an exception with a bad value in the EXC_RETURN number */
|
||||
uint16_t INVPC : 1;
|
||||
/* Attempts to execute a coprocessor instruction */
|
||||
uint16_t NOCP : 1;
|
||||
uint16_t UnusedBits : 4;
|
||||
/* Indicates that an unaligned access fault has taken place */
|
||||
uint16_t UNALIGNED : 1;
|
||||
/* Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set) */
|
||||
uint16_t DIVBYZERO0 : 1;
|
||||
} bits;
|
||||
} ufsr;
|
||||
} part;
|
||||
} cfsr;
|
||||
|
||||
/* Memory Management Fault Address Register (0xE000ED34) */
|
||||
uint32_t mmar;
|
||||
|
||||
/* Bus Fault Manage Address Register (0xE000ED38) */
|
||||
uint32_t bfar;
|
||||
|
||||
union {
|
||||
/* Hard Fault Status Register (0xE000ED2C) */
|
||||
uint32_t value;
|
||||
struct {
|
||||
uint32_t UnusedBits : 1;
|
||||
/* Indicates hard fault is caused by failed vector fetch */
|
||||
uint32_t VECTBL : 1;
|
||||
uint32_t UnusedBits2 : 28;
|
||||
/* Indicates hard fault is taken because of bus fault/memory management fault/usage fault */
|
||||
uint32_t FORCED : 1;
|
||||
/* Indicates hard fault is triggered by debug event */
|
||||
uint32_t DEBUGEVT : 1;
|
||||
} bits;
|
||||
} hfsr;
|
||||
|
||||
union {
|
||||
/* Debug Fault Status Register (0xE000ED30) */
|
||||
uint32_t value;
|
||||
struct {
|
||||
/* Halt requested in NVIC */
|
||||
uint32_t HALTED : 1;
|
||||
/* BKPT instruction executed */
|
||||
uint32_t BKPT : 1;
|
||||
/* DWT match occurred */
|
||||
uint32_t DWTTRAP : 1;
|
||||
/* Vector fetch occurred */
|
||||
uint32_t VCATCH : 1;
|
||||
/* EDBGRQ signal asserted */
|
||||
uint32_t EXTERNAL : 1;
|
||||
} bits;
|
||||
} dfsr;
|
||||
|
||||
/* Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional) */
|
||||
uint32_t afsr;
|
||||
} port_fault_regs_t;
|
||||
|
||||
enum fault_info {
|
||||
FAULT_INFO_ASSERT_ON_THREAD,
|
||||
FAULT_INFO_HFSR_VECTBL,
|
||||
FAULT_INFO_MFSR_IACCVIOL,
|
||||
FAULT_INFO_MFSR_DACCVIOL,
|
||||
FAULT_INFO_MFSR_MUNSTKERR,
|
||||
FAULT_INFO_MFSR_MSTKERR,
|
||||
FAULT_INFO_MFSR_MLSPERR,
|
||||
FAULT_INFO_BFSR_IBUSERR,
|
||||
FAULT_INFO_BFSR_PRECISERR,
|
||||
FAULT_INFO_BFSR_IMPREISERR,
|
||||
FAULT_INFO_BFSR_UNSTKERR,
|
||||
FAULT_INFO_BFSR_STKERR,
|
||||
FAULT_INFO_BFSR_LSPERR,
|
||||
FAULT_INFO_UFSR_UNDEFINSTR,
|
||||
FAULT_INFO_UFSR_INVSTATE,
|
||||
FAULT_INFO_UFSR_INVPC,
|
||||
FAULT_INFO_UFSR_NOCP,
|
||||
FAULT_INFO_UFSR_UNALIGNED,
|
||||
FAULT_INFO_UFSR_DIVBYZERO0,
|
||||
FAULT_INFO_DFSR_HALTED,
|
||||
FAULT_INFO_DFSR_BKPT,
|
||||
FAULT_INFO_DFSR_DWTTRAP,
|
||||
FAULT_INFO_DFSR_VCATCH,
|
||||
FAULT_INFO_DFSR_EXTERNAL,
|
||||
FAULT_INFO_MMAR,
|
||||
FAULT_INFO_BFAR,
|
||||
};
|
||||
|
||||
static const char *const fault_msg[] = {
|
||||
[FAULT_INFO_ASSERT_ON_THREAD] = "Assert on thread %s\n",
|
||||
[FAULT_INFO_HFSR_VECTBL] = "Hard fault is caused by failed vector fetch\n",
|
||||
[FAULT_INFO_MFSR_IACCVIOL] = "Memory management fault: instruction access violation\n",
|
||||
[FAULT_INFO_MFSR_DACCVIOL] = "Memory management fault: data access violation\n",
|
||||
[FAULT_INFO_MFSR_MUNSTKERR] = "Memory management fault: unstacking error\n",
|
||||
[FAULT_INFO_MFSR_MSTKERR] = "Memory management fault: stacking error\n",
|
||||
[FAULT_INFO_MFSR_MLSPERR] = "Memory management fault: floating-point lazy state preservation\n",
|
||||
[FAULT_INFO_BFSR_IBUSERR] = "Bus fault: instruction access violation\n",
|
||||
[FAULT_INFO_BFSR_PRECISERR] = "Bus fault: precise data access violation\n",
|
||||
[FAULT_INFO_BFSR_IMPREISERR] = "Bus fault: imprecise data access violation\n",
|
||||
[FAULT_INFO_BFSR_UNSTKERR] = "Bus fault: unstacking error\n",
|
||||
[FAULT_INFO_BFSR_STKERR] = "Bus fault: stacking error\n",
|
||||
[FAULT_INFO_BFSR_LSPERR] = "Bus fault: floating-point lazy state preservation\n",
|
||||
[FAULT_INFO_UFSR_UNDEFINSTR] = "Usage fault: undefined instruction\n",
|
||||
[FAULT_INFO_UFSR_INVSTATE] = "Usage fault: invalid state (e.g., ARM)\n",
|
||||
[FAULT_INFO_UFSR_INVPC] = "Usage fault: invalid EXC_RETURN\n",
|
||||
[FAULT_INFO_UFSR_NOCP] = "Usage fault: coprocessor instruction\n",
|
||||
[FAULT_INFO_UFSR_UNALIGNED] = "Usage fault: unaligned access\n",
|
||||
[FAULT_INFO_UFSR_DIVBYZERO0] = "Usage fault: divide by zero(can be set only if DIV_0_TRP is set)\n",
|
||||
[FAULT_INFO_DFSR_HALTED] = "Debug fault: halt requested in NVIC\n",
|
||||
[FAULT_INFO_DFSR_BKPT] = "Debug fault: BKPT instruction executed\n",
|
||||
[FAULT_INFO_DFSR_DWTTRAP] = "Debug fault: DWT match occurred\n",
|
||||
[FAULT_INFO_DFSR_VCATCH] = "Debug fault: Vector fetch occurred\n",
|
||||
[FAULT_INFO_DFSR_EXTERNAL] = "Debug fault: EDBGRQ signal asserted\n",
|
||||
[FAULT_INFO_MMAR] = "The memory management fault occurred address is %08x\n",
|
||||
[FAULT_INFO_BFAR] = "The bus fault occurred address is %08x\n",
|
||||
};
|
||||
|
||||
__PORT__ void HardFault_Handler(void);
|
||||
|
||||
__PORT__ void port_fault_diagnosis(void);
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT) && (TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT == 1u)
|
||||
__PORT__ uint32_t port_clz(uint32_t val);
|
||||
#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,281 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* 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.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016-2018 Armink (armink.ztl@gmail.com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* 'Software'), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "tos_k.h"
|
||||
#include "core_cm4.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__ k_cycle_t port_systick_max_reload_cycle(void)
|
||||
{
|
||||
return SysTick_LOAD_RELOAD_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
|
||||
__STATIC__ void port_fault_do_diagnosis(port_fault_regs_t *regs)
|
||||
{
|
||||
k_fault_log_writer("\n\n====================== Fault Diagnosis =====================\n");
|
||||
|
||||
if (regs->hfsr.bits.VECTBL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_HFSR_VECTBL]);
|
||||
}
|
||||
if (regs->hfsr.bits.FORCED) {
|
||||
/* Memory Management Fault */
|
||||
if (regs->cfsr.part.mfsr.value) {
|
||||
if (regs->cfsr.part.mfsr.bits.IACCVIOL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_IACCVIOL]);
|
||||
}
|
||||
if (regs->cfsr.part.mfsr.bits.DACCVIOL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_DACCVIOL]);
|
||||
}
|
||||
if (regs->cfsr.part.mfsr.bits.MUNSTKERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MUNSTKERR]);
|
||||
}
|
||||
if (regs->cfsr.part.mfsr.bits.MSTKERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MSTKERR]);
|
||||
}
|
||||
|
||||
if (regs->cfsr.part.mfsr.bits.MLSPERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MLSPERR]);
|
||||
}
|
||||
|
||||
if (regs->cfsr.part.mfsr.bits.MMARVALID) {
|
||||
if (regs->cfsr.part.mfsr.bits.IACCVIOL || regs->cfsr.part.mfsr.bits.DACCVIOL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MMAR], regs->mmar);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Bus Fault */
|
||||
if (regs->cfsr.part.bfsr.value) {
|
||||
if (regs->cfsr.part.bfsr.bits.IBUSERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_IBUSERR]);
|
||||
}
|
||||
if (regs->cfsr.part.bfsr.bits.PRECISERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_PRECISERR]);
|
||||
}
|
||||
if (regs->cfsr.part.bfsr.bits.IMPREISERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_IMPREISERR]);
|
||||
}
|
||||
if (regs->cfsr.part.bfsr.bits.UNSTKERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_UNSTKERR]);
|
||||
}
|
||||
if (regs->cfsr.part.bfsr.bits.STKERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_STKERR]);
|
||||
}
|
||||
|
||||
if (regs->cfsr.part.bfsr.bits.LSPERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_LSPERR]);
|
||||
}
|
||||
|
||||
if (regs->cfsr.part.bfsr.bits.BFARVALID) {
|
||||
if (regs->cfsr.part.bfsr.bits.PRECISERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFAR], regs->bfar);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* Usage Fault */
|
||||
if (regs->cfsr.part.ufsr.value) {
|
||||
if (regs->cfsr.part.ufsr.bits.UNDEFINSTR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_UNDEFINSTR]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.INVSTATE) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_INVSTATE]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.INVPC) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_INVPC]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.NOCP) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_NOCP]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.UNALIGNED) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_UNALIGNED]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.DIVBYZERO0) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_DIVBYZERO0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Debug Fault */
|
||||
if (regs->hfsr.bits.DEBUGEVT) {
|
||||
if (regs->dfsr.value) {
|
||||
if (regs->dfsr.bits.HALTED) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_HALTED]);
|
||||
}
|
||||
if (regs->dfsr.bits.BKPT) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_BKPT]);
|
||||
}
|
||||
if (regs->dfsr.bits.DWTTRAP) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_DWTTRAP]);
|
||||
}
|
||||
if (regs->dfsr.bits.VCATCH) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_VCATCH]);
|
||||
}
|
||||
if (regs->dfsr.bits.EXTERNAL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_EXTERNAL]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__PORT__ void port_fault_diagnosis(void)
|
||||
{
|
||||
port_fault_regs_t regs;
|
||||
|
||||
regs.syshndctrl.value = SCB->SHCSR;
|
||||
regs.cfsr.value = SCB->CFSR;
|
||||
regs.mmar = SCB->MMFAR;
|
||||
regs.bfar = SCB->BFAR;
|
||||
regs.hfsr.value = SCB->HFSR;
|
||||
regs.dfsr.value = SCB->DFSR;
|
||||
regs.afsr = SCB->AFSR;
|
||||
|
||||
port_fault_do_diagnosis(®s);
|
||||
}
|
||||
|
||||
/*------------------ 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,37 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* 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 1u
|
||||
#define TOS_CFG_CPU_BYTE_ORDER CPU_BYTE_ORDER_LITTLE_ENDIAN
|
||||
|
||||
#if (defined(ARMCC_V5) && !defined(__TARGET_FPU_SOFTVFP)) || \
|
||||
(defined(ARMCC_V6) && defined(__ARM_PCS_VFP))
|
||||
#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,188 @@
|
|||
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 port_clz
|
||||
|
||||
EXPORT PendSV_Handler
|
||||
|
||||
IMPORT k_curr_task
|
||||
IMPORT k_next_task
|
||||
|
||||
SCB_VTOR EQU 0xE000ED08
|
||||
NVIC_INT_CTRL EQU 0xE000ED04
|
||||
NVIC_SYSPRI14 EQU 0xE000ED22
|
||||
NVIC_PENDSV_PRI EQU 0xFF
|
||||
NVIC_PENDSVSET EQU 0x10000000
|
||||
|
||||
|
||||
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_clz
|
||||
port_clz
|
||||
CLZ R0, R0
|
||||
BX LR
|
||||
|
||||
|
||||
GLOBAL port_sched_start
|
||||
port_sched_start
|
||||
CPSID I
|
||||
|
||||
; set pendsv priority lowest
|
||||
; otherwise trigger pendsv in port_irq_context_switch will cause a context switch in irq
|
||||
; that would be a disaster
|
||||
MOV32 R0, NVIC_SYSPRI14
|
||||
MOV32 R1, NVIC_PENDSV_PRI
|
||||
STRB R1, [R0]
|
||||
|
||||
LDR R0, =SCB_VTOR
|
||||
LDR R0, [R0]
|
||||
LDR R0, [R0]
|
||||
MSR MSP, R0
|
||||
|
||||
; k_curr_task = k_next_task
|
||||
MOV32 R0, k_curr_task
|
||||
MOV32 R1, k_next_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
|
||||
; sp = k_next_task->sp
|
||||
LDR R0, [R2]
|
||||
; PSP = sp
|
||||
MSR PSP, R0
|
||||
|
||||
; using PSP
|
||||
MRS R0, CONTROL
|
||||
ORR R0, R0, #2
|
||||
MSR CONTROL, R0
|
||||
|
||||
ISB
|
||||
|
||||
; restore r4-11 from new process stack
|
||||
LDMFD SP!, {R4 - R11}
|
||||
|
||||
IF {FPU} != "SoftVFP"
|
||||
; ignore EXC_RETURN the first switch
|
||||
LDMFD SP!, {R0}
|
||||
ENDIF
|
||||
|
||||
; restore r0, r3
|
||||
LDMFD SP!, {R0 - R3}
|
||||
; load R12 and LR
|
||||
LDMFD SP!, {R12, LR}
|
||||
; load PC and discard xPSR
|
||||
LDMFD SP!, {R1, R2}
|
||||
|
||||
CPSIE I
|
||||
BX R1
|
||||
|
||||
|
||||
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
|
||||
|
||||
_context_save
|
||||
; R0-R3, R12, LR, PC, xPSR is saved automatically here
|
||||
IF {FPU} != "SoftVFP"
|
||||
; is it extended frame?
|
||||
TST LR, #0x10
|
||||
IT EQ
|
||||
VSTMDBEQ R0!, {S16 - S31}
|
||||
; S0 - S16, FPSCR saved automatically here
|
||||
|
||||
; save EXC_RETURN
|
||||
STMFD R0!, {LR}
|
||||
ENDIF
|
||||
|
||||
; save remaining regs r4-11 on process stack
|
||||
STMFD R0!, {R4 - R11}
|
||||
|
||||
; k_curr_task->sp = PSP
|
||||
MOV32 R5, k_curr_task
|
||||
LDR R6, [R5]
|
||||
; R0 is SP of process being switched out
|
||||
STR R0, [R6]
|
||||
|
||||
_context_restore
|
||||
; k_curr_task = k_next_task
|
||||
MOV32 R1, k_next_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R5]
|
||||
|
||||
; R0 = k_next_task->sp
|
||||
LDR R0, [R2]
|
||||
|
||||
; restore R4 - R11
|
||||
LDMFD R0!, {R4 - R11}
|
||||
|
||||
IF {FPU} != "SoftVFP"
|
||||
; restore EXC_RETURN
|
||||
LDMFD R0!, {LR}
|
||||
; is it extended frame?
|
||||
TST LR, #0x10
|
||||
IT EQ
|
||||
VLDMIAEQ R0!, {S16 - S31}
|
||||
ENDIF
|
||||
|
||||
; Load PSP with new process SP
|
||||
MSR PSP, R0
|
||||
CPSIE I
|
||||
; R0-R3, R12, LR, PC, xPSR restored automatically here
|
||||
; S0 - S16, FPSCR restored automatically here if FPCA = 1
|
||||
BX LR
|
||||
|
||||
ALIGN
|
||||
END
|
||||
|
||||
|
|
@ -0,0 +1,311 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* 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.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016-2018 Armink (armink.ztl@gmail.com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* 'Software'), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _PORT_H_
|
||||
#define _PORT_H_
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
typedef struct port_fault_regs {
|
||||
union {
|
||||
/* System Handler Control and State Register (0xE000ED24) */
|
||||
uint32_t value;
|
||||
struct {
|
||||
/* Read as 1 if memory management fault is active */
|
||||
uint32_t MEMFAULTACT : 1;
|
||||
/* Read as 1 if bus fault exception is active */
|
||||
uint32_t BUSFAULTACT : 1;
|
||||
uint32_t UnusedBits1 : 1;
|
||||
/* Read as 1 if usage fault exception is active */
|
||||
uint32_t USGFAULTACT : 1;
|
||||
uint32_t UnusedBits2 : 3;
|
||||
/* Read as 1 if SVC exception is active */
|
||||
uint32_t SVCALLACT : 1;
|
||||
/* Read as 1 if debug monitor exception is active */
|
||||
uint32_t MONITORACT : 1;
|
||||
uint32_t UnusedBits3 : 1;
|
||||
/* Read as 1 if PendSV exception is active */
|
||||
uint32_t PENDSVACT : 1;
|
||||
/* Read as 1 if SYSTICK exception is active */
|
||||
uint32_t SYSTICKACT : 1;
|
||||
/* Usage fault pended; usage fault started but was replaced by a higher-priority exception */
|
||||
uint32_t USGFAULTPENDED : 1;
|
||||
/* Memory management fault pended; memory management fault started but was replaced by a
|
||||
higher-priority exception */
|
||||
uint32_t MEMFAULTPENDED : 1;
|
||||
/* Bus fault pended; bus fault handler was started but was replaced by a higher-priority
|
||||
exception */
|
||||
uint32_t BUSFAULTPENDED : 1;
|
||||
/* SVC pended; SVC was started but was replaced by a higher-priority exception */
|
||||
uint32_t SVCALLPENDED : 1;
|
||||
/* Memory management fault handler enable */
|
||||
uint32_t MEMFAULTENA : 1;
|
||||
/* Bus fault handler enable */
|
||||
uint32_t BUSFAULTENA : 1;
|
||||
/* Usage fault handler enable */
|
||||
uint32_t USGFAULTENA : 1;
|
||||
} bits;
|
||||
} syshndctrl;
|
||||
|
||||
union {
|
||||
uint32_t value;
|
||||
|
||||
struct {
|
||||
union {
|
||||
/* Memory Management Fault Status Register (0xE000ED28) */
|
||||
uint8_t value;
|
||||
struct {
|
||||
/* Instruction access violation */
|
||||
uint8_t IACCVIOL : 1;
|
||||
/* Data access violation */
|
||||
uint8_t DACCVIOL : 1;
|
||||
uint8_t UnusedBits : 1;
|
||||
/* Unstacking error */
|
||||
uint8_t MUNSTKERR : 1;
|
||||
/* Stacking error */
|
||||
uint8_t MSTKERR : 1;
|
||||
/* Floating-point lazy state preservation (M4/M7) */
|
||||
uint8_t MLSPERR : 1;
|
||||
uint8_t UnusedBits2 : 1;
|
||||
/* Indicates the MMAR is valid */
|
||||
uint8_t MMARVALID : 1;
|
||||
} bits;
|
||||
} mfsr;
|
||||
|
||||
union {
|
||||
/* Bus Fault Status Register (0xE000ED29) */
|
||||
uint8_t value;
|
||||
struct {
|
||||
/* Instruction access violation */
|
||||
uint8_t IBUSERR : 1;
|
||||
/* Precise data access violation */
|
||||
uint8_t PRECISERR : 1;
|
||||
/* Imprecise data access violation */
|
||||
uint8_t IMPREISERR : 1;
|
||||
/* Unstacking error */
|
||||
uint8_t UNSTKERR : 1;
|
||||
/* Stacking error */
|
||||
uint8_t STKERR : 1;
|
||||
/* Floating-point lazy state preservation (M4/M7) */
|
||||
uint8_t LSPERR : 1;
|
||||
uint8_t UnusedBits : 1;
|
||||
/* Indicates BFAR is valid */
|
||||
uint8_t BFARVALID : 1;
|
||||
} bits;
|
||||
} bfsr;
|
||||
|
||||
union {
|
||||
/* Usage Fault Status Register (0xE000ED2A) */
|
||||
uint16_t value;
|
||||
struct {
|
||||
/* Attempts to execute an undefined instruction */
|
||||
uint16_t UNDEFINSTR : 1;
|
||||
/* Attempts to switch to an invalid state (e.g., ARM) */
|
||||
uint16_t INVSTATE : 1;
|
||||
/* Attempts to do an exception with a bad value in the EXC_RETURN number */
|
||||
uint16_t INVPC : 1;
|
||||
/* Attempts to execute a coprocessor instruction */
|
||||
uint16_t NOCP : 1;
|
||||
uint16_t UnusedBits : 4;
|
||||
/* Indicates that an unaligned access fault has taken place */
|
||||
uint16_t UNALIGNED : 1;
|
||||
/* Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set) */
|
||||
uint16_t DIVBYZERO0 : 1;
|
||||
} bits;
|
||||
} ufsr;
|
||||
} part;
|
||||
} cfsr;
|
||||
|
||||
/* Memory Management Fault Address Register (0xE000ED34) */
|
||||
uint32_t mmar;
|
||||
|
||||
/* Bus Fault Manage Address Register (0xE000ED38) */
|
||||
uint32_t bfar;
|
||||
|
||||
union {
|
||||
/* Hard Fault Status Register (0xE000ED2C) */
|
||||
uint32_t value;
|
||||
struct {
|
||||
uint32_t UnusedBits : 1;
|
||||
/* Indicates hard fault is caused by failed vector fetch */
|
||||
uint32_t VECTBL : 1;
|
||||
uint32_t UnusedBits2 : 28;
|
||||
/* Indicates hard fault is taken because of bus fault/memory management fault/usage fault */
|
||||
uint32_t FORCED : 1;
|
||||
/* Indicates hard fault is triggered by debug event */
|
||||
uint32_t DEBUGEVT : 1;
|
||||
} bits;
|
||||
} hfsr;
|
||||
|
||||
union {
|
||||
/* Debug Fault Status Register (0xE000ED30) */
|
||||
uint32_t value;
|
||||
struct {
|
||||
/* Halt requested in NVIC */
|
||||
uint32_t HALTED : 1;
|
||||
/* BKPT instruction executed */
|
||||
uint32_t BKPT : 1;
|
||||
/* DWT match occurred */
|
||||
uint32_t DWTTRAP : 1;
|
||||
/* Vector fetch occurred */
|
||||
uint32_t VCATCH : 1;
|
||||
/* EDBGRQ signal asserted */
|
||||
uint32_t EXTERNAL : 1;
|
||||
} bits;
|
||||
} dfsr;
|
||||
|
||||
/* Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional) */
|
||||
uint32_t afsr;
|
||||
} port_fault_regs_t;
|
||||
|
||||
enum fault_info {
|
||||
FAULT_INFO_ASSERT_ON_THREAD,
|
||||
FAULT_INFO_HFSR_VECTBL,
|
||||
FAULT_INFO_MFSR_IACCVIOL,
|
||||
FAULT_INFO_MFSR_DACCVIOL,
|
||||
FAULT_INFO_MFSR_MUNSTKERR,
|
||||
FAULT_INFO_MFSR_MSTKERR,
|
||||
FAULT_INFO_MFSR_MLSPERR,
|
||||
FAULT_INFO_BFSR_IBUSERR,
|
||||
FAULT_INFO_BFSR_PRECISERR,
|
||||
FAULT_INFO_BFSR_IMPREISERR,
|
||||
FAULT_INFO_BFSR_UNSTKERR,
|
||||
FAULT_INFO_BFSR_STKERR,
|
||||
FAULT_INFO_BFSR_LSPERR,
|
||||
FAULT_INFO_UFSR_UNDEFINSTR,
|
||||
FAULT_INFO_UFSR_INVSTATE,
|
||||
FAULT_INFO_UFSR_INVPC,
|
||||
FAULT_INFO_UFSR_NOCP,
|
||||
FAULT_INFO_UFSR_UNALIGNED,
|
||||
FAULT_INFO_UFSR_DIVBYZERO0,
|
||||
FAULT_INFO_DFSR_HALTED,
|
||||
FAULT_INFO_DFSR_BKPT,
|
||||
FAULT_INFO_DFSR_DWTTRAP,
|
||||
FAULT_INFO_DFSR_VCATCH,
|
||||
FAULT_INFO_DFSR_EXTERNAL,
|
||||
FAULT_INFO_MMAR,
|
||||
FAULT_INFO_BFAR,
|
||||
};
|
||||
|
||||
static const char *const fault_msg[] = {
|
||||
[FAULT_INFO_ASSERT_ON_THREAD] = "Assert on thread %s\n",
|
||||
[FAULT_INFO_HFSR_VECTBL] = "Hard fault is caused by failed vector fetch\n",
|
||||
[FAULT_INFO_MFSR_IACCVIOL] = "Memory management fault: instruction access violation\n",
|
||||
[FAULT_INFO_MFSR_DACCVIOL] = "Memory management fault: data access violation\n",
|
||||
[FAULT_INFO_MFSR_MUNSTKERR] = "Memory management fault: unstacking error\n",
|
||||
[FAULT_INFO_MFSR_MSTKERR] = "Memory management fault: stacking error\n",
|
||||
[FAULT_INFO_MFSR_MLSPERR] = "Memory management fault: floating-point lazy state preservation\n",
|
||||
[FAULT_INFO_BFSR_IBUSERR] = "Bus fault: instruction access violation\n",
|
||||
[FAULT_INFO_BFSR_PRECISERR] = "Bus fault: precise data access violation\n",
|
||||
[FAULT_INFO_BFSR_IMPREISERR] = "Bus fault: imprecise data access violation\n",
|
||||
[FAULT_INFO_BFSR_UNSTKERR] = "Bus fault: unstacking error\n",
|
||||
[FAULT_INFO_BFSR_STKERR] = "Bus fault: stacking error\n",
|
||||
[FAULT_INFO_BFSR_LSPERR] = "Bus fault: floating-point lazy state preservation\n",
|
||||
[FAULT_INFO_UFSR_UNDEFINSTR] = "Usage fault: undefined instruction\n",
|
||||
[FAULT_INFO_UFSR_INVSTATE] = "Usage fault: invalid state (e.g., ARM)\n",
|
||||
[FAULT_INFO_UFSR_INVPC] = "Usage fault: invalid EXC_RETURN\n",
|
||||
[FAULT_INFO_UFSR_NOCP] = "Usage fault: coprocessor instruction\n",
|
||||
[FAULT_INFO_UFSR_UNALIGNED] = "Usage fault: unaligned access\n",
|
||||
[FAULT_INFO_UFSR_DIVBYZERO0] = "Usage fault: divide by zero(can be set only if DIV_0_TRP is set)\n",
|
||||
[FAULT_INFO_DFSR_HALTED] = "Debug fault: halt requested in NVIC\n",
|
||||
[FAULT_INFO_DFSR_BKPT] = "Debug fault: BKPT instruction executed\n",
|
||||
[FAULT_INFO_DFSR_DWTTRAP] = "Debug fault: DWT match occurred\n",
|
||||
[FAULT_INFO_DFSR_VCATCH] = "Debug fault: Vector fetch occurred\n",
|
||||
[FAULT_INFO_DFSR_EXTERNAL] = "Debug fault: EDBGRQ signal asserted\n",
|
||||
[FAULT_INFO_MMAR] = "The memory management fault occurred address is %08x\n",
|
||||
[FAULT_INFO_BFAR] = "The bus fault occurred address is %08x\n",
|
||||
};
|
||||
|
||||
__PORT__ void HardFault_Handler(void);
|
||||
|
||||
__PORT__ void port_fault_diagnosis(void);
|
||||
#endif
|
||||
|
||||
#if defined(TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT) && (TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT == 1u)
|
||||
__PORT__ uint32_t port_clz(uint32_t val);
|
||||
#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_ */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue