This commit is contained in:
unknown 2023-12-01 09:31:09 +08:00
commit 6709c81281
8995 changed files with 8035127 additions and 0 deletions

35
.gitignore vendored Normal file
View File

@ -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/*

20
.travis.yml Normal file
View File

@ -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

172
LICENSE Normal file
View File

@ -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 LicenseVersion 2.0, January 2004http://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.

198
README.md Normal file
View File

@ -0,0 +1,198 @@
# 开放原子开源基金会首批孵化项目
![](./doc/image/introduction/TencentOS_tiny_log.png)
[![license](http://img.shields.io/badge/license-BSD-blue.svg)](https://github.com/Tencent/TencentOS-tiny/blob/master/LICENSE)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-blue.svg)](https://github.com/Tencent/TencentOS-tiny/pulls)
[![Build status](https://travis-ci.org/Tencent/TencentOS-tiny.svg?branch=master)](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整体架构
![](./doc/image/introduction/TencentOS_tiny_Architecture.png)
TencentOS tiny 主体架构图,从下到上主要包括:
**CPU 库** TencentOS tiny 支持的 CPU IP 核架构,当前主要支持 ARM Cortex M0/3/4/7Cortex A7RISC-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.6KBROM 1.8KB
典型 LoraWAN 及传感器应用RAM 3.3KBROM 12KB
### (2).低功耗
休眠最低功耗低至 2uA
支持外设功耗管理框架
### (3).丰富的 IoT 组件
集成主流 IoT 协议栈
多种通信模组SAL层适配框架
支持 OTA 升级
提供简单易用端云 API加速用户业务接入腾讯云
### (4).可靠的安全框架
多样化的安全分级方案
均衡安全需求&成本控制
### (5).良好的可移植性
内核及IoT组件高度解耦提供标准适配层
提供自动化移植工具,提升开发效率
### (6).便捷的调试手段
提供云化的最后一屏调试功能
故障现场信息自动上传云平台,方便开发人员调试分析
## 3、TencentOS tiny携手合作伙伴共建IoT生态
![](./doc/image/introduction/Partners.png)
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 联合合作伙伴(南京厚德物联网)设计了定制开发板,如下图:
![](./doc/image/introduction/EVB_MX.png)
- [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 开发者,工作人员会根据备注进行审核:
![](./doc/image/introduction/qq.png)
# 九、第三方开发者评测
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)

128
README_en.md Normal file
View File

@ -0,0 +1,128 @@
![](./doc/image/introduction/TencentOS_tiny_log.png)
[![license](http://img.shields.io/badge/license-BSD-blue.svg)](https://github.com/Tencent/TencentOS-tiny/blob/master/LICENSE)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-blue.svg)](https://github.com/Tencent/TencentOS-tiny/pulls)
[![Build status](https://travis-ci.org/Tencent/TencentOS-tiny.svg?branch=master)](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
![](./doc/image/introduction/TencentOS_tiny_Architecture_en.png)
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
![](./doc/image/introduction/Partners_en.png)
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 guideKEIL version](./doc/10.Porting_Manual_for_KEIL.md)
- [TencentOS tiny Porting guideIAR version](./doc/11.Porting_Manual_for_IAR.md)
- [TencentOS tiny Porting guideGCC 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:
![](./doc/image/introduction/EVB_MX.png)
- [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:
![](./doc/image/introduction/qq.png)

48
arch/Makefile Normal file
View File

@ -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

74
arch/arc/arcem/port.h Normal file
View File

@ -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_ */

103
arch/arc/arcem/port_c.c Normal file
View File

@ -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

View File

@ -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_ */

319
arch/arc/arcem/port_s.s Normal file
View File

@ -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]

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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

View File

@ -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_ */

266
arch/arc/common/tos_cpu.c Normal file
View File

@ -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

View File

@ -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();
}

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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

View File

@ -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_ */

View File

@ -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 */

View File

@ -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

View File

@ -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_ */

View File

@ -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 */

View File

@ -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_ */

View File

@ -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

View File

@ -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_ */

View File

@ -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 */

View File

@ -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_ */

View File

@ -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

View File

@ -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_ */

View File

@ -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 */

View File

@ -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_ */

View File

@ -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

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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)
{
}

View File

@ -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 */

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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

View File

@ -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

View File

@ -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_ */

View File

@ -0,0 +1,7 @@
#ifndef _SYSTICK_H_
#define _SYSTICK_H_
void systick_init(k_tick_t tick_per_second);
#endif /* _SYSTICK_H_ */

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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_ */

View File

@ -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 */

View File

@ -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_ */

View File

@ -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 */

View File

@ -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

View File

@ -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) }
}

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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

View File

@ -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_ */

View File

@ -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 */

View File

@ -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

View File

@ -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_ */

View File

@ -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 */

View File

@ -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_ */

View File

@ -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

View File

@ -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_ */

View File

@ -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 */

View File

@ -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_ */

View File

@ -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

View File

@ -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_ */

View File

@ -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 */

View File

@ -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_ */

View File

@ -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

View File

@ -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_ */

View File

@ -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(&regs);
}
/*------------------ 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 */

View File

@ -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_ */

View File

@ -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

View File

@ -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_ */

View File

@ -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(&regs);
}
/*------------------ 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 */

View File

@ -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_ */

View File

@ -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

View File

@ -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_ */

View File

@ -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(&regs);
}
__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 */

View File

@ -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_ */

View File

@ -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

View File

@ -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_ */

View File

@ -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(&regs);
}
/*------------------ 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 */

View File

@ -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_ */

View File

@ -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

View File

@ -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