feat: 引入UniProton内核源码

Close #I5T8GN
Signed-off-by: zhushengle <zhushengle@huawei.com>
This commit is contained in:
zhushengle
2022-09-26 19:50:41 +08:00
parent ed51fe4acb
commit be61d3bbd5
259 changed files with 27337 additions and 0 deletions
+90
View File
@@ -0,0 +1,90 @@
cmake_minimum_required(VERSION 3.14.1) #cmake最低版本要求
project(UniProton LANGUAGES C ASM) #项目名字为UniProton
############################## 外部传入变量 ##############################
set(CPU_TYPE "$ENV{CPU_TYPE}" )
set(PLAM_TYPE "$ENV{PLAM_TYPE}" )
set(LIB_TYPE "$ENV{LIB_TYPE}" )
set(UNIPROTON_PACKING_PATH "$ENV{UNIPROTON_PACKING_PATH}" ) #UNIPROTON_PACKING_PATH
set(COMPILE_OPTION "$ENV{COMPILE_OPTION}" ) #编译选项 空为默认全编译 还有coverity/fortify
set(CONFIG_FILE_PATH "$ENV{CONFIG_FILE_PATH}" ) #defconfig及其头文件所在目录
string(TOUPPER ${PLAM_TYPE} PLAM_TYPE_UP) #转大写
set(SYSTEM "$ENV{SYSTEM}" )
set(CORE "$ENV{CORE}" )
set(LIB_RUN_TYPE "$ENV{LIB_RUN_TYPE}" )
set(HOME_PATH "$ENV{HOME_PATH}" )
set(BUILD_MACHINE_PLATFORM "$ENV{BUILD_MACHINE_PLATFORM}" )
set(RPROTON_BINARY_DIR "$ENV{RPROTON_BINARY_DIR}" )
if("${RPROTON_BINARY_DIR}" STREQUAL "")
# this branch will be taken
set(RPROTON_BINARY_DIR ${PROJECT_SOURCE_DIR}/build/output)
else()
set(RPROTON_BINARY_DIR ${RPROTON_BINARY_DIR}/UniProton/tmp/output)
endif()
message("UniProton BINARY_DIR=${RPROTON_BINARY_DIR}")
######该参数的判断逻辑脚本来实现一个XCache的开关######
if (CACHE)
find_program(CACHE_FOUND ${CACHE})
set(CACHE_TOOL "${CACHE}")
endif()
if(CACHE_FOUND)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CACHE_TOOL})
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CACHE_TOOL})
endif()
############################## 公共函数定义导入 ##############################
include(${HOME_PATH}/cmake/functions/uniproton_functions.cmake)
############################## 编译参数 ##################################
#下述这些参数的设置要放在项目设置之后!
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${RPROTON_BINARY_DIR}/${CPU_TYPE}/${PLAM_TYPE}/${LIB_RUN_TYPE}") #库文件输出路径
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY})
############################## 调试打印 ##############################
message("CMAKE_C_COMPILER is ${CMAKE_C_COMPILER}")
message("CMAKE_AR is ${CMAKE_AR}")
message("CMAKE_LINKER is ${CMAKE_LINKER}")
message("CMAKE_INSTALL_PREFIX is ${CMAKE_INSTALL_PREFIX}")
message("BUILD_MACHINE_PLATFORM= ${BUILD_MACHINE_PLATFORM}")
message("CONFIG_FILE_PATH= ${CONFIG_FILE_PATH}")
if (${COMPILE_MODE} STREQUAL "debug")
add_compile_options("-g") #编译 -g 选项,打开后可以在sdk调试时看到调试信息
endif()
message("=============== COMPILE_MODE is ${COMPILE_MODE} ===============")
############################## 通过.config文件引入编译宏 ##################
# #函数import_kconfig把.config文件中的定义转换为cmake变量,用于后续子文件夹中决定是否编译某库
import_kconfig(${CONFIG_FILE_PATH}/defconfig)
##############################include 头文件##############################
#可能和平台相关
include_directories(
${CONFIG_FILE_PATH}
./src/arch/include
./src/core/ipc/include
./src/core/kernel/include
./src/include/uapi
./src/mem/include
./src/om/include
./src/utility/lib/include
./platform/libboundscheck/include
)
if (NOT ${COMPILE_OPTION} STREQUAL "UniProton")
###添加安全库的cmakelists
add_subdirectory(platform)
endif()
if (NOT ${COMPILE_OPTION} STREQUAL "sec")
###添加源码目录的cmakelists
add_subdirectory(src)
##############################不同平台,根据需要链接出不同的lib库############
include(./cmake/tool_chain/${CPU_TYPE}_${PLAM_TYPE}.cmake)
endif()
+127
View File
@@ -0,0 +1,127 @@
木兰宽松许可证, 第2版
木兰宽松许可证, 第2版
2020年1月 http://license.coscl.org.cn/MulanPSL2
您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第2版(“本许可证”)的如下条款的约束:
0. 定义
“软件”是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。
“贡献”是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。
“贡献者”是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。
“法人实体”是指提交贡献的机构及其“关联实体”。
“关联实体”是指,对“本许可证”下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。
1. 授予版权许可
每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。
2. 授予专利许可
每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。
3. 无商标许可
“本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。
4. 分发限制
您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。
5. 免责声明与责任限制
“软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。
6. 语言
“本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文版为准。
条款结束
如何将木兰宽松许可证,第2版,应用到您的软件
如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步:
1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字;
2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中;
3, 请将如下声明文本放入每个源文件的头部注释中。
Copyright (c) [Year] [name of copyright holder]
[Software Name] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
Mulan Permissive Software LicenseVersion 2
Mulan Permissive Software LicenseVersion 2 (Mulan PSL v2)
January 2020 http://license.coscl.org.cn/MulanPSL2
Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v2 (this License) with the following terms and conditions:
0. Definition
Software means the program and related documents which are licensed under this License and comprise all Contribution(s).
Contribution means the copyrightable work licensed by a particular Contributor under this License.
Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License.
Legal Entity means the entity making a Contribution and all its Affiliates.
Affiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, control means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity.
1. Grant of Copyright License
Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not.
2. Grant of Patent License
Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed. The patent license shall not apply to any modification of the Contribution, and any other combination which includes the Contribution. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken.
3. No Trademark License
No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in Section 4.
4. Distribution Restriction
You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software.
5. Disclaimer of Warranty and Limitation of Liability
THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO MATTER HOW ITS CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
6. Language
THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL.
END OF THE TERMS AND CONDITIONS
How to Apply the Mulan Permissive Software LicenseVersion 2 (Mulan PSL v2) to Your Software
To apply the Mulan PSL v2 to your work, for easy identification by recipients, you are suggested to complete following three steps:
i Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner;
ii Create a file named “LICENSE” which contains the whole context of this License in the first directory of your software package;
iii Attach the statement to the appropriate annotated syntax at the beginning of each source file.
Copyright (c) [Year] [name of copyright holder]
[Software Name] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
+44
View File
@@ -0,0 +1,44 @@
## UniProton介绍
UniProton主要目的在于为上层业务软件提供一个统一的操作系统平台,屏蔽底层硬件差异,并提供强大的调试功能。使得业务软件可在不同的硬件平台之间快速移植,方便产品芯片选型,降低硬件采购成本和软件维护成本。
一、搭建UniProton开发环境
----------
#### 1、下载源码
```bash
git clone https://gitee.com/openeuler/UniProton.git
```
##### 源码目录
[源码目录介绍](./doc/design/architecture_design.md)
#### 2、创建开发工程
[hello word示例](./doc/getting_started.md)
#### 3、编译
[编译步骤](./doc/UniProton_build.md)
二、功能介绍
----------
- [任务](./doc/design/task.md)
- [中断](./doc/design/hwi.md)
- [事件](./doc/design/event.md)
- [队列](./doc/design/queue.md)
- [信号量](./doc/design/sem.md)
- [内存管理](./doc/design/mem.md)
- [软件定时器](./doc/design/timer.md)
- [异常](./doc/design/exc.md)
- [错误处理](./doc/design/err.md)
- [cpu占用率](./doc/design/cpup.md)
三、免责声明
----------
1. 当前开源版本仅支持cortex_m4芯片,默认编译脚本的安全编译选项仅支持栈保护,其他选项由用户根据需要自行添加。
2. 遵循MulanPSL2开源许可协议
四、如何贡献
----------
我们非常欢迎新贡献者加入到项目中来,也非常高兴能为新加入贡献者提供指导和帮助。在您贡献代码前,需要先签署[CLA](https://openeuler.org/en/cla.html)。
+259
View File
@@ -0,0 +1,259 @@
#!/usr/bin/env python3
# coding=utf-8
# The build entrance of UniProton.
# Copyright © Huawei Technologies Co., Ltd. 2010-2020. All rights reserved.
import os
import sys
import time
import shutil
import subprocess
import platform
from sys import argv
UniProton_home = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, "%s/cmake/common/build_auxiliary_script"%UniProton_home)
from make_buildef import make_buildef
sys.path.insert(0, "%s/build/uniproton_ci_lib"%UniProton_home)
import globle
from logs import BuilderNolog, log_msg
from get_config_info import *
class Compile:
# 根据makechoice获取config的配置的环境,compile_mode lib_type,
def get_config(self, cpu_type, cpu_plat):
self.compile_mode = get_compile_mode()
self.lib_type, self.plam_type, self.hcc_path, self.kconf_dir, self.system, self.core = get_cpu_info(cpu_type, cpu_plat, self.build_machine_platform)
if not self.compile_mode and self.lib_type and self.plam_type and self.hcc_path and self.kconf_dir:
log_msg('error', 'load config.xml env error')
sys.exit(0)
self.config_file_path = '%s/build/uniproton_config/config_%s'%(self.home_path, self.kconf_dir)
self.objcopy_path = self.hcc_path
def setCmdEnv(self):
self.build_time_tag = time.strftime('%Y-%m-%d_%H:%M:00')
self.log_dir = '%s/logs/%s' % (self.build_dir, self.cpu_type)
self.log_file = '%s.log' % self.kconf_dir
def SetCMakeEnviron(self):
os.environ["CPU_TYPE"] = self.cpu_type
os.environ["PLAM_TYPE"] = self.plam_type
os.environ["LIB_TYPE"] = self.lib_type
os.environ["COMPILE_OPTION"] = self.compile_option
os.environ["HCC_PATH"] = self.hcc_path
os.environ["UNIPROTON_PACKING_PATH"] = self.UniProton_packing_path
os.environ["CONFIG_FILE_PATH"] = self.config_file_path
os.environ["LIB_RUN_TYPE"] = self.lib_run_type
os.environ["HOME_PATH"] = self.home_path
os.environ["COMPILE_MODE"] = self.compile_mode
os.environ["BUILD_MACHINE_PLATFORM"] = self.build_machine_platform
os.environ["SYSTEM"] = self.system
os.environ["CORE"] = self.core
os.environ["OBJCOPY_PATH"] = self.objcopy_path
os.environ['PATH'] = '%s:%s' % (self.hcc_path, os.getenv('PATH'))
# 环境准备,准备执行cmakemakemakebuildfileCmakeList需要的环境
# 每次compile之前请调用该函数
def prepare_env(self, cpu_type, choice):
# makebuildfile需要的环境kconf_dir
# cmake需要的环境cmake_env_pathhome_pathcmakelist所在的路径),home_path,
# make cmd拼接需要的环境:home_path,UniProton_make_jx,log_dir,log_filebuild_time_tag UniProton_make_jx
#根据cpu_type, choice从config文件中获取并初始化初始化hcc_path plam_type, kconf_dir
#根据输入分支获取
#从编译镜像环境获取
self.get_config(cpu_type, choice)
self.setCmdEnv()
self.SetCMakeEnviron()
#获取编译环境是arm64还是x86,用户不感知,并将其写入环境变量。
def getOsPlatform(self):
self.cmake_env_path = get_tool_info('cmake', 'tool_path')
if platform.uname()[-1] == 'aarch64':
self.build_machine_platform = 'arm64'
else:
self.build_machine_platform = 'x86'
# 获取当前编译的路径信息,配置文件信息,编译选项信息
def __init__(self, cpu_type: str, make_option="normal", lib_run_type="FPGA", choice="ALL", make_phase="ALL",
UniProton_packing_path=""):
# 当前路径信息
self.system = ""
self.objcopy_path = ""
self.builder = None
self.compile_mode = ""
self.core = ""
self.plam_type = ""
self.kconf_dir = ""
self.build_tmp_dir = ""
self.log_dir = ""
self.lib_type = ""
self.hcc_path = ""
self.log_file = ""
self.config_file_path = ""
self.build_time_tag = ""
self.build_dir = globle.build_dir
self.home_path = globle.home_path
self.kbuild_path = globle.kbuild_path
# 当前选项信息
self.cpu_type = cpu_type
self.compile_option = make_option
self.lib_run_type = lib_run_type
self.make_choice = choice.lower()
self.make_phase = make_phase
self.UniProton_packing_path = UniProton_packing_path if make_phase == "CREATE_CMAKE_FILE" else '%s/output'%self.home_path
self.UniProton_binary_dir = os.getenv('RPROTON_BINARY_DIR')
self.UniProton_install_file_option = os.getenv('RPROTON_INSTALL_FILE_OPTION')
self.UniProton_make_jx = 'VERBOSE=1' if self.UniProton_install_file_option == 'SUPER_BUILD' else 'VERBOSE=1 -j$(nproc)'
# 当前编译平台信息
self.getOsPlatform()
#调用cmake生成Makefile文件,需要
def CMake(self):
if self.UniProton_binary_dir:
self.build_tmp_dir = '%s/output/tmp/%s' % (self.UniProton_binary_dir, self.kconf_dir)
else:
self.build_tmp_dir = '%s/output/tmp/%s' % (self.build_dir, self.kconf_dir)
os.environ['BUILD_TMP_DIR'] = self.build_tmp_dir
if not os.path.exists(self.build_tmp_dir):
os.makedirs(self.build_tmp_dir)
if not os.path.exists(self.log_dir):
os.makedirs(self.log_dir)
log_msg('info', 'BUILD_TIME_TAG %s' % self.build_time_tag)
self.builder = BuilderNolog(os.path.join(self.log_dir, self.log_file))
if self.make_phase in ['CREATE_CMAKE_FILE', 'ALL']:
real_path = os.path.realpath(self.build_tmp_dir)
if os.path.exists(real_path):
shutil.rmtree(real_path)
os.makedirs(self.build_tmp_dir)
#拼接cmake命令
if self.compile_option == 'fortify':
cmd = '%s/cmake %s -DCMAKE_TOOLCHAIN_FILE=%s/cmake/tool_chain/uniproton_tool_chain.cmake ' \
'-DCMAKE_C_COMPILER_LAUNCHER="sourceanalyzer;-b;%sproject" ' \
'-DCMAKE_INSTALL_PREFIX=%s &> %s/%s' % (
self.cmake_env_path, self.home_path, self.home_path, self.cpu_type,
self.UniProton_packing_path, self.log_dir, self.log_file)
elif self.compile_option == 'hllt':
cmd = '%s/cmake %s -DCMAKE_TOOLCHAIN_FILE=%s/cmake/tool_chain/uniproton_tool_chain.cmake ' \
'-DCMAKE_C_COMPILER_LAUNCHER="lltwrapper" -DCMAKE_INSTALL_PREFIX=%s &> %s/%s' % (
self.cmake_env_path, self.home_path, self.home_path, self.UniProton_packing_path, self.log_dir, self.log_file)
else:
cmd = '%s/cmake %s -DCMAKE_TOOLCHAIN_FILE=%s/cmake/tool_chain/uniproton_tool_chain.cmake ' \
'-DCMAKE_INSTALL_PREFIX=%s &> %s/%s' % (
self.cmake_env_path, self.home_path, self.home_path, self.UniProton_packing_path, self.log_dir, self.log_file)
#执行cmake命令
if self.builder.run(cmd, cwd=self.build_tmp_dir, env=None):
log_msg('error', 'generate makefile failed!')
return False
log_msg('info', 'generate makefile succeed.')
return True
def UniProton_clean(self):
for foldername,subfoldernames,filenames in os.walk(self.build_dir):
for subfoldername in subfoldernames:
if subfoldername in ['logs','output','__pycache__']:
folder_path = os.path.join(foldername,subfoldername)
shutil.rmtree(os.path.relpath(folder_path))
for filename in filenames:
if filename == 'prt_buildef.h':
file_dir = os.path.join(foldername,filename)
os.remove(os.path.relpath(file_dir))
if os.path.exists('%s/cmake/common/build_auxiliary_script/__pycache__'%self.home_path):
shutil.rmtree('%s/cmake/common/build_auxiliary_script/__pycache__'%self.home_path)
if os.path.exists('%s/output'%self.home_path):
shutil.rmtree('%s/output'%self.home_path)
if os.path.exists('%s/tools/SRE/x86-win32/sp_makepatch/makepatch'%self.home_path):
os.remove('%s/tools/SRE/x86-win32/sp_makepatch/makepatch'%self.home_path)
if os.path.exists('%s/build/prepare/__pycache__'%self.home_path):
shutil.rmtree('%s/build/prepare/__pycache__'%self.home_path)
return True
def make(self):
if self.make_phase in ['EXECUTING_MAKE', 'ALL']:
self.builder.run('make clean', cwd=self.build_tmp_dir, env=None)
tmp = sys.argv
if self.builder.run(
'make all %s &>> %s/%s' % (
self.UniProton_make_jx, self.log_dir, self.log_file), cwd=self.build_tmp_dir, env=None):
log_msg('error', 'make %s %s failed!' % (self.cpu_type, self.plam_type))
return False
sys.argv = tmp
if self.compile_option in ['normal', 'coverity', 'single']:
if self.builder.run('make install %s &>> %s/%s' % (self.UniProton_make_jx, self.log_dir, self.log_file), cwd=self.build_tmp_dir, env=None):
log_msg('error', 'make install failed!')
return False
if os.path.exists('%s/%s' % (self.log_dir, self.log_file)):
self.builder.log_format()
log_msg('info', 'make %s %s succeed.' % (self.cpu_type, self.plam_type))
return True
def SdkCompaile(self)->bool:
# 判断该环境中是否需要编译
if self.hcc_path == 'None':
return True
self.MakeBuildef()
if self.CMake() and self.make():
log_msg('info', 'make %s %s lib succeed!' % (self.cpu_type, self.make_choice))
return True
else:
log_msg('info', 'make %s %s lib failed!' % (self.cpu_type, self.make_choice))
return False
# 对外函数,调用后根据类初始化时的值进行编译
def UniProtonCompile(self):
#清除UniProton缓存
if self.cpu_type == 'clean':
log_msg('info', 'UniProton clean')
return self.UniProton_clean()
# 根据cpu的编译平台配置相应的编译环境。
if self.make_choice == "all":
for make_choice in globle.cpu_plat[self.cpu_type]:
self.prepare_env(self.cpu_type, make_choice)
if not self.SdkCompaile():
return False
else:
self.prepare_env(self.cpu_type, self.make_choice)
if not self.SdkCompaile():
return False
return True
def MakeBuildef(self):
if not make_buildef(globle.home_path,self.kconf_dir,"CREATE"):
sys.exit(1)
log_msg('info', 'make_buildef_file.sh %s successfully.' % self.kconf_dir)
# argv[1]: cpu_plat 表示要编译的平台:
# argv[2]: compile_option 控制编译选项,调用不同的cmake参数,目前只有normal coverity hllt fortify single(是否编译安全c,组件化独立构建需求)
# argv[3]: lib_run_type lib库要跑的平台 faga sim等
# argv[4]: make_choice
# argv[5]: make_phase 全量构建选项
# argv[6]: UniProton_packing_path lib库的安装位置
if __name__ == "__main__":
default_para = ("all", "normal", "FPGA", "ALL", "ALL", "")
if len(argv) == 1:
para = [default_para[i] for i in range(0, len(default_para))]
else:
para = [argv[i+1] if i < len(argv) - 1 else default_para[i] for i in range(0,len(default_para))]
cur_cpu_type = para[0].lower()
cur_compile_option = para[1].lower()
cur_lib_run_type = para[2]
cur_make_choice = para[3]
cur_make_phase = para[4]
cur_UniProton_packing_path = para[5]
for plat in globle.cpus_[cur_cpu_type]:
UniProton_build = Compile(plat, cur_compile_option, cur_lib_run_type, cur_make_choice, cur_make_phase, cur_UniProton_packing_path)
if not UniProton_build.UniProtonCompile():
sys.exit(1)
sys.exit(0)
+80
View File
@@ -0,0 +1,80 @@
#!/usr/bin/env python3
# coding=utf-8
# The build entrance of UniProton.
# Copyright © Huawei Technologies Co., Ltd. 2010-2020. All rights reserved.
import xml.dom.minidom
import sys
import logging
import globle
from logs import BuilderNolog, log_msg
logging.basicConfig(level=logging.NOTSET)
logging.info(globle.config_dir)
config_tree = xml.dom.minidom.parse(globle.config_dir)
EXCEPTION_LIST = (AssertionError, AttributeError, IOError,
ImportError, IndentationError,
IndexError, KeyError, NameError,
SyntaxError, TypeError, ValueError)
def getNodeValue(node, index = 0):
return node.childNodes[index].nodeValue
def getXmlNode(node, name):
return node.getElementsByTagName(name)
def getNodeAtrrValue(node, attrname):
return node.getAttribute(attrname)
def getChildNodeValueByNodeName(farthe_node, nodename, index = 0):
return farthe_node.getElementsByTagName(nodename)[0].childNodes[index].nodeValue
def getChildNodeByNodeAtrr(farthe_node, node_name, atrr_name, strr_vlue):
for node in farthe_node.getElementsByTagName(node_name):
if node.getAttribute(atrr_name).startswith(strr_vlue):
return node
return False
# 根据cputype获取hcc_path, kconf_dir, plam_type
def get_cpu_info(cpu_type, cpu_plat, os_plat):
nameNode = "project"
cpu_list = config_tree.documentElement.getElementsByTagName(nameNode)
hcc_path, kconf_dir, plam_type, lib_type = "", "", "", ""
try:
for cpu in cpu_list:
if getNodeAtrrValue(cpu, "cpu_type") == cpu_type:
lib_type = getChildNodeValueByNodeName(cpu, "lib_type")
plam_type = getChildNodeValueByNodeName(getChildNodeByNodeAtrr(cpu, "platform", "plat_name", cpu_plat), "name")
hcc_path = getChildNodeValueByNodeName(getChildNodeByNodeAtrr(cpu, "platform", "plat_name", cpu_plat), "compile_path_{}".format(os_plat))
kconf_dir = getChildNodeValueByNodeName(getChildNodeByNodeAtrr(cpu, "platform", "plat_name", cpu_plat), "kconf_dir")
except EXCEPTION_LIST:
log_msg('error', "get cpu {} config info error:{} {}".format(cpu_type, cpu_plat, os_plat))
sys.exit(0)
system, core = "None", "None"
try:
for cpu in cpu_list:
if getNodeAtrrValue(cpu, "cpu_type") == cpu_type:
core = getChildNodeValueByNodeName(getChildNodeByNodeAtrr(cpu, "platform", "plat_name", cpu_plat), "core")
system = getChildNodeValueByNodeName(cpu, "system")
except EXCEPTION_LIST:
system = "None"
return lib_type, plam_type, hcc_path, kconf_dir, system, core
def get_tool_info(tool_name, node_name):
tool_list = config_tree.documentElement.getElementsByTagName("tool")
try:
for tool in tool_list:
if getNodeAtrrValue(tool, "tool_name") == tool_name:
return getChildNodeValueByNodeName(tool, node_name)
except EXCEPTION_LIST:
log_msg("error", "get tool config info error:{} {}".format(tool_name, node_name))
sys.exit(0)
return False
def get_compile_mode():
nameNode = "UniProton_compile_mode"
cpu_list = config_tree.documentElement.getElementsByTagName(nameNode)
compile_mode = getNodeValue(cpu_list[0])
return compile_mode
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/env python3
# coding=utf-8
# The build entrance of UniProton.
# Copyright © Huawei Technologies Co., Ltd. 2010-2020. All rights reserved.
import os
build_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
home_path = os.path.dirname(build_dir)
config_dir = os.path.join(home_path,'config.xml')
kbuild_path = '%s/cmake/common/build_auxiliary_script' % home_path
cpus_ = {'all': ['clean', 'm4'],
'clean':['clean'],
'm4': ['m4']
}
cpu_plat = {'m4': ['cortex']
}
+64
View File
@@ -0,0 +1,64 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# The build entrance of UniProton.
# Copyright © Huawei Technologies Co., Ltd. 2010-2020. All rights reserved.
import os
import re
import sys
import time
import logging
import globle
logging.basicConfig(level=logging.NOTSET)
class BuilderNolog():
def __init__(self,log_file):
self.log_file = log_file
self.loglevel = 'INFO'
def run(self, cmd, cwd=os.getcwd(), env=None):
exit_code = os.system('cd %s && %s' % (cwd, cmd))
if exit_code != 0:
with open(self.log_file) as file_handle:
for line in file_handle.readlines():
logging.info(line)
logging.info("\n--[INFO] more message in logfile [%s] env: [%s]" ,self.log_file, env)
return exit_code
def log_format(self):
try:
sys.path.append(("%s%s") % (globle.home_path, "/../cmake"))
import logcode_format
formatter = (logcode_format.init_format(os.getcwd().split('/')[-1]))
except ImportError:
formatter = '%(asctime)s -- %(levelname)s [UniProton] -- : %(message)s'
logger_root = logging.getLogger()
for handler in logger_root.handlers:
logger_root.removeHandler(handler)
with open(self.log_file, 'r') as rd:
lines = rd.readlines()
os.remove(self.log_file)
logformat = logging.Formatter(formatter)
fh = logging.FileHandler(self.log_file, mode='a', encoding=sys.getdefaultencoding())
fh.setLevel(self.loglevel)
fh.setFormatter(logformat)
logger = logging.getLogger('UniProton')
logger.setLevel(self.loglevel)
for handler in logger.handlers:
logger.removeHandler(handler)
logger.addHandler(fh)
for line in lines:
logger.info(line.strip())
return
def log_msg(level,msg):
logging.info('[%s] %s %s %s', level.upper(),'#'*20,msg,'#'*20)
+116
View File
@@ -0,0 +1,116 @@
#
# Automatically generated file; DO NOT EDIT.
# UniProton Configuration
#
#
# Arch Modules Configuration
#
CONFIG_OS_ARCH_ARMV7_M=y
#
# ARM7-M Sepecfic Configuration
#
CONFIG_INTERNAL_OS_CORTEX_M4=y
CONFIG_INTERNAL_OS_PLATFORM_M4=y
#
# M4 Sepecfic Configuration
#
#
# Generic Configuration
#
CONFIG_OS_HARDWARE_PLATFORM="OS_CORTEX_M4"
CONFIG_OS_CPU_TYPE="OS_STM32F407"
CONFIG_OS_MAX_CORE_NUM=1
CONFIG_INTERNAL_OS_BYTE_ORDER_LE=y
CONFIG_OS_BYTE_ORDER="OS_LITTLE_ENDIAN"
#
# Core Modules Configuration
#
#
# IPC Modules Configuration
#
#
# Event feature configuration
#
CONFIG_OS_OPTION_EVENT=y
CONFIG_OS_OPTION_QUEUE=y
#
# Semaphore feature configuration
#
#
# Kernel Modules Configuration
#
#
# IRQ Modules Configuration
#
CONFIG_OS_OPTION_HWI_COMBINE=y
CONFIG_OS_OPTION_HWI_PRIORITY=y
CONFIG_OS_OPTION_HWI_ATTRIBUTE=y
CONFIG_OS_OPTION_HWI_MAX_NUM_CONFIG=y
#
# Exc Modules Configuration
#
#
# Task module Configuration
#
CONFIG_OS_OPTION_TASK=y
#
# TASK features configuration
#
CONFIG_OS_OPTION_TASK_DELETE=y
CONFIG_OS_OPTION_TASK_SUSPEND=y
CONFIG_OS_OPTION_TASK_INFO=y
CONFIG_OS_OPTION_TASK_YIELD=y
CONFIG_OS_TSK_PRIORITY_HIGHEST=0
CONFIG_OS_TSK_PRIORITY_LOWEST=31
CONFIG_OS_TSK_NUM_OF_PRIORITIES=32
CONFIG_OS_TSK_CORE_BYTES_IN_PID=2
#
# Timer Modules Configuration
#
CONFIG_INTERNAL_OS_SWTMR=y
#
# MM Modules Configuration
#
#
# OM Modules Configuration
#
CONFIG_OS_OPTION_CPUP=y
#
# CPUP features configuration
#
CONFIG_INTERNAL_OS_CPUP_THREAD=y
CONFIG_OS_OPTION_CPUP_WARN=y
#
# Error Report Module Configuration
#
#
# Hook feature configuration
#
#
# security Modules Configuration
#
CONFIG_OS_OPTION_RND=y
#
# Utility Modules Configuration
#
@@ -0,0 +1,229 @@
#!/usr/bin/env python3
# coding=utf-8
# Transfer kconfig configuration file to buildef/config file.
# Copyright © Huawei Technologies Co., Ltd. 2010-2020. All rights reserved.
import os
import sys
import time
import getopt
import re
import logging
import codecs
logging.basicConfig(level=logging.NOTSET)
HEADER_TYPE_BUILD = 0
HEADER_TYPE_CONFIG = 1
HEADER_TYPE_INVALID = 2
def cmd_help():
logging.info("Interpret the configuration file which was generated by Kconfig tool, and")
logging.info("Transfer it to header file which will be used in C code")
logging.info("Command format:")
logging.info(" Kconfig2macro.py [-e][-f configFileName] [-o headerFileName]")
logging.info("The default configFileName is .config")
logging.info("The default headerFileName is config.h")
def headerType(in_file):
with open(in_file, 'r') as fd_in:
lines = fd_in.readlines()
for line in lines:
if line.find("CONFIG_OS_HARDWARE_PLATFORM=") >= 0:
return HEADER_TYPE_BUILD
return HEADER_TYPE_CONFIG
def write_header(out_file):
with codecs.open(out_file,
'w',
encoding='gbk',
errors='ignore') as fd_out:
file_path, file_name = os.path.split(out_file)
name = ((str(file_name)).split('.'))[0]
header_macro = '%s_H' % (str.upper(name))
text = r'''/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: the common part buildef.h
*/
'''
text = '%s#ifndef %s\n' % (text, header_macro)
text = '%s#define %s\n' % (text, header_macro)
text = '%s\n' % (text)
text = '%s#ifdef __cplusplus\n#if __cplusplus\nextern "C" {\n#endif\n#endif\n' % (text)
fd_out.write(text)
return 0
def get_macro_fix(macro):
prefix = ""
suffix = "\n"
if macro == "OS_HARDWARE_PLATFORM" or macro == "OS_CPU_TYPE" or macro == "OS_BYTE_ORDER":
prefix = '#ifndef %s\n' % (macro)
suffix = "#endif\n\n"
return prefix, suffix
def write_macro(fd_out, line, flag):
export_flag = False
match_s = re.search(r'\w+', line)
if match_s is None:
return
macro = match_s.group()
if not macro.startswith("CONFIG_"):
return
macro = macro[len("CONFIG_"):]
if macro.startswith("INTERNAL_"):
return
if macro.startswith("EXPORT_"):
macro = macro[len("EXPORT_"):]
export_flag = flag
if line.find("is not set") >= 0:
value = "NO"
else:
expression = line.split("=", 1)
if len(expression) < 2:
return
value = expression[1].strip()
if value == 'y':
value = ""
prefix, suffix = get_macro_fix(macro)
text = '%s#define %s %s\n%s' %(prefix ,macro, value.strip('"'), suffix)
if export_flag == True or flag == False:
fd_out.write(text.rstrip() + "\n\n")
def write_config(in_file, out_file, flag):
with codecs.open(out_file, 'a+') as fd_out, open(in_file) as fd_in:
fd_out.write("\n")
lines = fd_in.readlines()
for line in lines:
if line.startswith('##'):
fd_out(line.replace("##", "/*") + "*/")
elif line.startswith("CONFIG_"):
write_macro(fd_out, line, flag)
return 0
def write_def_config(filename, string):
with open(filename, 'r', errors='ignore') as fp:
for line in fp:
if string in line:
return line
with codecs.open(file, 'a+') as fd_in:
text = '#define %-35s NO \n\n' %(str)
fd_in.write(text)
return 0
def write_external_macro(out_file):
with codecs.open(out_file, 'a+') as fd_out:
text = '#define OS_LITTLE_ENDIAN 0x1234\n\n#define OS_BIG_ENDIAN 0x4321\n\n#define OS_CORTEX_M4 0x1\n\n#define OS_STM32F407 0x1\n\n'
fd_out.write(text)
return 0
def write_c_external_tail(out_file):
with codecs.open(out_file, 'a+') as fd_out:
text = '#ifdef __cplusplus\n#if __cplusplus\n}\n#endif\n#endif\n'
fd_out.write(text)
return 0
def write_tail(out_file):
with codecs.open(out_file, 'a+') as fd_out:
text = '\n#endif\n'
fd_out.write(text)
return 0
def kconfig2macro(in_file, out_file, flag):
header_type = headerType(in_file)
if header_type == HEADER_TYPE_INVALID:
return -10
ret = write_header(out_file)
if ret != 0:
return ret
ret = write_config(in_file, out_file, flag)
if ret != 0:
return ret
ret = write_external_macro(out_file)
if ret != 0:
return ret
ret = write_c_external_tail(out_file)
if ret != 0:
return ret
ret = write_tail(out_file)
if ret != 0:
return ret
return 0
def do_cmd(argv, flag):
in_file = ".config"
out_file = "config.h"
try:
opts, args = getopt.getopt(argv,"ehf:o:",["help", "inFile=", "outFile="])
except getopt.GetoptError:
cmd_help()
return -1
if len(args) > 0:
cmd_help()
return -2
for opt, arg in opts:
if opt in ('-h', '--help'):
cmd_help()
return 0
elif opt in ('-e'):
flag = True
elif opt in ('-f', '--inFile'):
in_file = arg
elif opt in ('-o', '--outFile'):
out_file = arg
else:
logging.error("ERROR: Invalid Input %s", opt)
cmd_help()
return -3
if os.path.exists(in_file) == False:
logging.info("config input file <%s> doesn't exist", in_file)
return -4
return kconfig2macro(in_file, out_file, flag)
if __name__ == "__main__":
res = do_cmd(sys.argv[1:], False)
sys.exit(res)
@@ -0,0 +1,31 @@
#!/usr/bin/env python3
# coding=utf-8
# Transfer kconfig configuration file to buildef/config file.
# Copyright © Huawei Technologies Co., Ltd. 2010-2020. All rights reserved.
import os
import sys
import logging
from Kconfig2macro import do_cmd
logging.basicConfig(level=logging.NOTSET)
def make_buildef(home_path, kconf_dir, choice):
kconfig_dir = "{}/build/uniproton_config/config_{}/defconfig".format(home_path,kconf_dir)
buildef_file = "{}/build/uniproton_config/config_{}/prt_buildef.h".format(home_path,kconf_dir)
if choice == "CREATE":
paras = ["-f", kconfig_dir, "-o", buildef_file]
if do_cmd(paras, False) != 0:
logging.info("build prt_buildef.h failed.")
return False
logging.info("build prt_buildef.h succeed.")
elif choice == "EXPORT":
paras = ["-e", "-f", kconfig_dir, "-o", buildef_file]
if do_cmd(paras, False) != 0:
logging.info("export prt_buildef.h failed.")
return False
logging.info("export prt_buildef.h succeed.")
else:
os.remove(buildef_file)
return True
@@ -0,0 +1,62 @@
#!/bin/bash
# Copyright © Huawei Technologies Co., Ltd. 2010-2020. All rights reserved.
set -e
if [ $# != 3 ] ; then
echo "USAGE: $0 AR_TOOL_PATH CK_LIB_PATH CK_LIB_SUFFIX"
exit 1;
fi
AR_TOOL_PATH="$1"
CK_LIB_PATH="$2"
CK_LIB_SUFFIX="$3"
file=lib"${CK_LIB_SUFFIX}"
if [ "${CPU_TYPE}" = "m4" ] ; then
ARNAME=arm-none-eabi-ar ; OBJCOPYNAME=arm-none-eabi-objcopy;
else
ARNAME=ar; OBJCOPYNAME=objcopy;
fi
sleep 2
pushd "$CK_LIB_PATH"
##为什么不加这一行要报错
if [ "${CPU_TYPE}" = "m4" ] ; then
[ -n tmp_"${file}" ] && rm -rf tmp_"${file}"
fi
mkdir tmp_"${file}"
mv "$file" tmp_"${file}"/
pushd tmp_"${file}"
"$AR_TOOL_PATH"/"${ARNAME}" -x "$file"
# 删除某变量指定的目录下所有文件。
# 通过对变量${FILE_PATH}进行判断,当${FILE_PATH}为空时,不会错误删除根目录下的文件。
[ -n "${file}" ] && rm -rf "${file}"
if [ "${CPU_TYPE}" = "m4" ] ; then
find . -name '*.s.o'| awk -F "." '{print $2}'|xargs -I'{}' mv ./{}.s.o ./{}.o
find . -name '*.S.o'| awk -F "." '{print $2}'|xargs -I'{}' mv ./{}.S.o ./{}.o
find . -name '*.c.o'| awk -F "." '{print $2}'|xargs -I'{}' mv ./{}.c.o ./{}.o
for i in $(ls *.o);
do
if [ -f "${i}" ] ; then
"${AR_TOOL_PATH}"/"${OBJCOPYNAME}" --remove-section=.comment -I elf32-littlearm -O elf32-littlearm "${i}" "${i}".oooo
"${AR_TOOL_PATH}"/"${OBJCOPYNAME}" --strip-unneeded "${i}".oooo
mv "${i}".oooo "${i}"
fi
done
fi
"$AR_TOOL_PATH"/"${ARNAME}" -r -D "$file" *.o
mv "$file" ../
popd
# 删除某变量指定的目录下所有文件。
# 通过对变量${FILE_PATH}进行判断,当${FILE_PATH}为空时,不会错误删除根目录下的文件。
[ -n tmp_"${file}" ] && rm -rf tmp_"${file}"
popd
exit 0
+171
View File
@@ -0,0 +1,171 @@
# Date: 2019-11-11
# Copyright © Huawei Technologies Co., Ltd. 2010-2020. All rights reserved.
###########################################################################
############################## 公共函数定义区域 ##############################
## 1. import defconfig
##把.config文件转换为cmake命名空间的变量,比如把CONFIG_OS_ARCH_ARM32VX=y 转化为 cmake变量
function(import_kconfig config_file)##.config文件转换为cmake命名空间的变量
#### 读取Config文件
file(STRINGS ${config_file} config_list REGEX "^CONFIG_" ENCODING "UTF-8")#### 读取Config文件
##处理各个匹配行
foreach (config ${config_list})##处理各个匹配行
##获取变量值
##字符串匹配‘=’号
string(REGEX MATCH "=(.+$)" conf_value ${config})##字符串匹配‘=’号
## 获取匹配值
set(conf_value ${CMAKE_MATCH_1})##获取匹配值
##匹配CONFIG_OS_HARDWARE_PLATFORM="OS_ARM7" 这种有""的情形
if("${conf_value}" MATCHES "^\"(.*)\"$")
##设置环境变量值
set(conf_value ${CMAKE_MATCH_1})##设置环境变量值
##定义结束
endif()##定义结束
##获取变量名
##字符串匹配‘=’号
string(REGEX MATCH "[^=]+" conf_name ${config})##字符串匹配‘=’号
##声明cmake全局变量
##设置环境变量值
set("${conf_name}" "${conf_value}" PARENT_SCOPE)##设置环境变量值
##message("${conf_name}=${conf_value}")
##遍历结束符
endforeach()##遍历结束符
##功能结束符
endfunction()##功能结束符
function(cc_object target sources cppincs cflags component_name working_directory)
# @target Object: the name of the target
# @sources List[str]: the code source path of list
# @cppincs List[str]: the include directories path of list
# @cppdefines List[str]: the defines of list
# @cflags List[str]: the c compile flags of list
# @component_name str: the component name of the atrget
# @working_directory str: the directory of command execute
list(JOIN ${cppincs} "\t-I" target_incflags)
set(obj_install_dir ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/${component_name})
file(MAKE_DIRECTORY ${obj_install_dir})
foreach(source_path IN LISTS ${sources})
get_filename_component(source_name ${source_path} NAME)
# .c替换为.eln
string(REGEX REPLACE \\.c \.o target_name ${source_name})
string(REPLACE ${working_directory}/ "" new_source_path ${source_path})
string(REGEX REPLACE .*/ "" current_directory ${working_directory})
add_custom_command(
OUTPUT ${obj_install_dir}/${target_name}
COMMAND ${cc} ${${cflags}} -I${target_incflags} -o ${obj_install_dir}/${target_name} -c ${new_source_path}
DEPENDS ${source_path}
WORKING_DIRECTORY ${working_directory}
)
add_custom_target(
${target_name}_custom
ALL
DEPENDS ${obj_install_dir}/${target_name}
)
list(APPEND ${target}_list_dep ${target_name}_custom )
list(APPEND ${target}_list__ ${obj_install_dir}/${target_name} )
endforeach()
set(${target}_PATH_LIST ${${target}_list__} PARENT_SCOPE)
set(${target}_NAME_LIST ${${target}_list_dep} PARENT_SCOPE)
endfunction()
function(asm_object target sources cflags component_name working_directory)
# @target Object: the name of the target
# @sources List[str]: the code source path of list
# @cppincs List[str]: the include directories path of list
# @cppdefines List[str]: the defines of list
# @cflags List[str]: the c compile flags of list
# @component_name str: the component name of the atrget
# @working_directory str: the directory of command execute
set(obj_install_dir ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/${component_name})
file(MAKE_DIRECTORY ${obj_install_dir})
foreach(source_path IN LISTS ${sources})
get_filename_component(source_name ${source_path} NAME)
string(REGEX REPLACE \\.asm \.eln target_name ${source_name})
string(REPLACE ${working_directory}/ "" new_source_path ${source_path})
string(REGEX REPLACE .*/ "" current_directory ${working_directory})
add_custom_command(
OUTPUT ${obj_install_dir}/${target_name}
COMMAND ${asm} ${${cflags}} -o ${obj_install_dir}/${target_name} -c ${new_source_path}
DEPENDS ${source_path}
WORKING_DIRECTORY ${working_directory}
)
add_custom_target(
${target_name}_custom
ALL
DEPENDS ${obj_install_dir}/${target_name}
)
list(APPEND ${target}_list_dep ${target_name}_custom )
list(APPEND ${target}_list__ ${obj_install_dir}/${target_name} )
endforeach()
set(${target}_PATH_LIST ${${target}_list__} PARENT_SCOPE)
set(${target}_NAME_LIST ${${target}_list_dep} PARENT_SCOPE)
endfunction()
function(ar_library target_name target_suffix target_path ar_flag object_name object_path)
# @target Object: the name of the target
# @sources List[str]: the code source path of list
# @cppincs List[str]: the include directories path of list
# @cppdefines List[str]: the defines of list
# @cflags List[str]: the c compile flags of list
# @component_name str: the component name of the atrget
# @working_directory str: the directory of command execute
add_custom_command(
OUTPUT ${target_path}/${target_name}.${target_suffix}
COMMAND ${ar} ${ar_flag} ${target_path}/${target_name}.${target_suffix} ${object_path}
WORKING_DIRECTORY ${target_path}
)
add_custom_target(
${target_name}
ALL
DEPENDS ${target_path}/${target_name}.${target_suffix}
)
foreach(object_target ${object_name})
add_dependencies(${target_name} ${object_target})
endforeach()
endfunction()
function(link_library target_name target_path link_flag object_name object_path)
# @target Object: the name of the target
# @sources List[str]: the code source path of list
# @cppincs List[str]: the include directories path of list
# @cppdefines List[str]: the defines of list
# @cflags List[str]: the c compile flags of list
# @component_name str: the component name of the atrget
# @working_directory str: the directory of command execute
add_custom_command(
OUTPUT ${target_path}/${target_name}
COMMAND ${link} ${${link_flag}} -o ${target_path}/${target_name} ${object_path}
WORKING_DIRECTORY ${target_path}
)
add_custom_target(
${target_name}
ALL
DEPENDS ${target_path}/${target_name}
)
foreach(object_target ${object_name})
add_dependencies(${target_name} ${object_target})
endforeach()
endfunction()
@@ -0,0 +1,14 @@
@PACKAGE_INIT@
include(${CMAKE_CURRENT_LIST_DIR}/UniProton-m4-cortex-targets.cmake)
set_and_check(INSTALL_M4_CORTEX_BASE_DIR "@PACKAGE_INSTALL_M4_CORTEX_BASE_DIR@")
set_and_check(INSTALL_M4_CORTEX_INCLUDE_DIR "@PACKAGE_INSTALL_M4_CORTEX_INCLUDE_DIR@")
set_and_check(INSTALL_M4_CORTEX_INCLUDE_SEC_DIR "@PACKAGE_INSTALL_M4_CORTEX_INCLUDE_SEC_DIR@")
set_and_check(INSTALL_M4_CORTEX_ARCHIVE_DIR "@PACKAGE_INSTALL_M4_CORTEX_ARCHIVE_DIR@")
set_and_check(INSTALL_M4_CORTEX_ARCHIVE_SEC_DIR "@PACKAGE_INSTALL_M4_CORTEX_ARCHIVE_SEC_DIR@")
set_and_check(INSTALL_M4_CORTEX_ARCHIVE_CONFIG_DIR "@PACKAGE_INSTALL_M4_CORTEX_ARCHIVE_CONFIG_DIR@")
set_and_check(INSTALL_M4_CORTEX_CONFIG_DIR "@PACKAGE_INSTALL_M4_CORTEX_CONFIG_DIR@")
check_required_components(UniProton-m4-cortex)
+256
View File
@@ -0,0 +1,256 @@
set(BUILD_DIR "$ENV{BUILD_TMP_DIR}" ) #version id
set(OBJCOPY_PATH "$ENV{OBJCOPY_PATH}" ) #OBJCOPY_PATH
##最终的链接目标,会生成对应的.a库
#################################################
## arch代码
#################################################
list(APPEND ARCH_SRCS
$<TARGET_OBJECTS:prt_hw_boot>
$<TARGET_OBJECTS:prt_port>
$<TARGET_OBJECTS:prt_dispatch>
$<TARGET_OBJECTS:prt_hwi>
$<TARGET_OBJECTS:prt_exc>
$<TARGET_OBJECTS:prt_hw_exc>
$<TARGET_OBJECTS:prt_vector>
$<TARGET_OBJECTS:prt_vi_dispatch>
$<TARGET_OBJECTS:prt_hw_tick>
$<TARGET_OBJECTS:prt_hw_tick_minor>
$<TARGET_OBJECTS:prt_hw>
$<TARGET_OBJECTS:prt_div64>
)
#################################################
## kernel代码
#################################################
list(APPEND KERNEL_SRCS
$<TARGET_OBJECTS:prt_sem>
$<TARGET_OBJECTS:prt_sem_init>
$<TARGET_OBJECTS:prt_sem_minor>
$<TARGET_OBJECTS:prt_irq>
$<TARGET_OBJECTS:prt_sys>
$<TARGET_OBJECTS:prt_sys_init>
$<TARGET_OBJECTS:prt_sys_time>
$<TARGET_OBJECTS:prt_amp_task>
$<TARGET_OBJECTS:prt_amp_task_del>
$<TARGET_OBJECTS:prt_amp_task_init>
$<TARGET_OBJECTS:prt_amp_task_minor>
$<TARGET_OBJECTS:prt_task>
$<TARGET_OBJECTS:prt_taskself_id>
$<TARGET_OBJECTS:prt_task_attrib>
$<TARGET_OBJECTS:prt_task_del>
$<TARGET_OBJECTS:prt_task_global>
$<TARGET_OBJECTS:prt_task_info>
$<TARGET_OBJECTS:prt_task_init>
$<TARGET_OBJECTS:prt_task_minor>
$<TARGET_OBJECTS:prt_task_priority>
$<TARGET_OBJECTS:prt_task_sem>
$<TARGET_OBJECTS:prt_tick>
$<TARGET_OBJECTS:prt_tick_init>
$<TARGET_OBJECTS:prt_timer>
$<TARGET_OBJECTS:prt_swtmr>
$<TARGET_OBJECTS:prt_swtmr_init>
$<TARGET_OBJECTS:prt_swtmr_minor>
$<TARGET_OBJECTS:prt_kexc>
$<TARGET_OBJECTS:prt_exc>
$<TARGET_OBJECTS:prt_timer_minor>
)
list(APPEND IPC_SRCS
$<TARGET_OBJECTS:prt_event>
$<TARGET_OBJECTS:prt_queue>
$<TARGET_OBJECTS:prt_queue_del>
$<TARGET_OBJECTS:prt_queue_minor>
$<TARGET_OBJECTS:prt_queue_init>
)
list(APPEND MEM_SRCS
$<TARGET_OBJECTS:prt_fscmem>
$<TARGET_OBJECTS:prt_mem>
)
list(APPEND OM_SRCS
$<TARGET_OBJECTS:prt_cpup>
$<TARGET_OBJECTS:prt_cpup_minor>
$<TARGET_OBJECTS:prt_cpup_thread>
$<TARGET_OBJECTS:prt_cpup_thread_64>
$<TARGET_OBJECTS:prt_cpup_thread_init>
$<TARGET_OBJECTS:prt_cpup_warn>
$<TARGET_OBJECTS:prt_err>
$<TARGET_OBJECTS:prt_err_init>
$<TARGET_OBJECTS:prt_hook_init>
$<TARGET_OBJECTS:prt_rnd_set>
)
list(APPEND BASE_LIB_SRCS
$<TARGET_OBJECTS:prt_lib_math64>
$<TARGET_OBJECTS:prt_lib_version>
)
#编译结果
string(TOUPPER ${PLAM_TYPE} PLAM_TYPE_UP)
string(TOUPPER ${CPU_TYPE} CPU_TYPE_UP)
#编译通用的.a库
add_library(CortexMXarch STATIC "${ARCH_SRCS}")
add_library(CortexMXkernel STATIC "${KERNEL_SRCS}" "${BASE_LIB_SRCS}")
add_library(CortexMXmem STATIC "${MEM_SRCS}")
add_library(CortexMXom STATIC "${OM_SRCS}")
add_library(CortexMXipc STATIC "${IPC_SRCS}")
set_target_properties(CortexMXarch PROPERTIES SUFFIX ".lib")
set_target_properties(CortexMXkernel PROPERTIES SUFFIX ".lib")
set_target_properties(CortexMXmem PROPERTIES SUFFIX ".lib")
set_target_properties(CortexMXom PROPERTIES SUFFIX ".lib")
set_target_properties(CortexMXipc PROPERTIES SUFFIX ".lib")
add_custom_target(cleanobj)
add_custom_command(TARGET cleanobj POST_BUILD
COMMAND echo "Finish Building!"
)
if (${COMPILE_MODE} STREQUAL "debug")
message("=============== COMPILE_MODE is ${COMPILE_MODE} ===============")
else()
add_custom_command(
TARGET CortexMXarch
POST_BUILD
COMMAND sh ${PROJECT_SOURCE_DIR}/cmake/common/build_auxiliary_script/make_lib_rename_file_type.sh ${OBJCOPY_PATH} ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} "CortexMXarch.lib"
)
add_custom_command(
TARGET CortexMXkernel
POST_BUILD
COMMAND sh ${PROJECT_SOURCE_DIR}/cmake/common/build_auxiliary_script/make_lib_rename_file_type.sh ${OBJCOPY_PATH} ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} "CortexMXkernel.lib"
)
add_custom_command(
TARGET CortexMXmem
POST_BUILD
COMMAND sh ${PROJECT_SOURCE_DIR}/cmake/common/build_auxiliary_script/make_lib_rename_file_type.sh ${OBJCOPY_PATH} ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} "CortexMXmem.lib"
)
add_custom_command(
TARGET CortexMXom
POST_BUILD
COMMAND sh ${PROJECT_SOURCE_DIR}/cmake/common/build_auxiliary_script/make_lib_rename_file_type.sh ${OBJCOPY_PATH} ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} "CortexMXom.lib"
)
add_custom_command(
TARGET CortexMXipc
POST_BUILD
COMMAND sh ${PROJECT_SOURCE_DIR}/cmake/common/build_auxiliary_script/make_lib_rename_file_type.sh ${OBJCOPY_PATH} ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} "CortexMXipc.lib"
)
endif()
####以下为m4 make install打包脚本#####
set(m4_cortex_export modules)
# 下面的变量分别定义了安装根目录、头文件安装目录、动态库安装目录、静态库安装目录、OBJECT文件安装目录、可执行程序安装目录、配置文件安装目录。
# 注意:所有安装路径必须是相对CMAKE_INSTALL_PREFIX的相对路径,不可以使用绝对路径!!!
# 否则安装目录下的配置文件(foo-config.cmake, foo-tragets.cmake等)拷贝到其它目录时无法工作。
set(INSTALL_M4_CORTEX_BASE_DIR .)
set(INSTALL_M4_CORTEX_INCLUDE_DIR UniProton/include)
set(INSTALL_M4_CORTEX_INCLUDE_SEC_DIR libboundscheck/include)
set(INSTALL_M4_CORTEX_ARCHIVE_DIR UniProton/lib/cortex_m4)
set(INSTALL_M4_CORTEX_ARCHIVE_SEC_DIR libboundscheck/lib/cortex_m4)
set(INSTALL_M4_CORTEX_ARCHIVE_CONFIG_DIR UniProton/config)
set(INSTALL_M4_CORTEX_CONFIG_DIR cmake/cortex_m4)
include(CMakePackageConfigHelpers)
configure_package_config_file(${PROJECT_SOURCE_DIR}/cmake/tool_chain/m4-cortex-config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/UniProton-m4-cortex-config.cmake
INSTALL_DESTINATION ${INSTALL_M4_CORTEX_CONFIG_DIR}
PATH_VARS
INSTALL_M4_CORTEX_BASE_DIR
INSTALL_M4_CORTEX_INCLUDE_DIR
INSTALL_M4_CORTEX_INCLUDE_SEC_DIR
INSTALL_M4_CORTEX_ARCHIVE_DIR
INSTALL_M4_CORTEX_ARCHIVE_SEC_DIR
INSTALL_M4_CORTEX_ARCHIVE_CONFIG_DIR
INSTALL_M4_CORTEX_CONFIG_DIR
INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}
)
install(EXPORT ${m4_cortex_export}
NAMESPACE UniProton::
FILE UniProton-m4-cortex-targets.cmake
DESTINATION ${INSTALL_M4_CORTEX_CONFIG_DIR}
)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/UniProton-m4-cortex-config.cmake
DESTINATION ${INSTALL_M4_CORTEX_CONFIG_DIR}
)
install(TARGETS
CortexMXarch
CortexMXkernel
CortexMXmem
CortexMXom
CortexMXipc
EXPORT ${m4_cortex_export}
ARCHIVE DESTINATION ${INSTALL_M4_CORTEX_ARCHIVE_DIR}/
)
if (${COMPILE_OPTION} STREQUAL "coverity" OR ${COMPILE_OPTION} STREQUAL "fortify" OR ${COMPILE_OPTION} STREQUAL "UniProton")
message("Don't Install Sec Lib In ${COMPILE_OPTION}")
else()
install(TARGETS
CortexMXsec_c
EXPORT ${m4_cortex_export}
ARCHIVE DESTINATION ${INSTALL_M4_CORTEX_ARCHIVE_SEC_DIR}
)
if (NOT "${RPROTON_INSTALL_FILE_OPTION}" STREQUAL "SUPER_BUILD")
##{GLOB 所有文件 | GLOB_RECURSE 递归查找文件&文件夹}
file(GLOB glob_sec_files ${PROJECT_SOURCE_DIR}/platform/libboundscheck/include/*.h)
install(FILES
${glob_sec_files}
DESTINATION ${INSTALL_M4_CORTEX_INCLUDE_SEC_DIR}
)
endif()
endif()
install(FILES
${PROJECT_SOURCE_DIR}/build/uniproton_config/config_m4/prt_buildef.h
DESTINATION ${INSTALL_M4_CORTEX_ARCHIVE_CONFIG_DIR}/cortex_m4/config_m4
)
if (NOT "${RPROTON_INSTALL_FILE_OPTION}" STREQUAL "SUPER_BUILD")
##{GLOB 所有文件 | GLOB_RECURSE 递归查找文件&文件夹}
install(FILES
${PROJECT_SOURCE_DIR}/src/config/prt_config.c
${PROJECT_SOURCE_DIR}/src/config/prt_config_internal.h
${PROJECT_SOURCE_DIR}/src/config/config/prt_config.h
DESTINATION ${INSTALL_M4_CORTEX_ARCHIVE_CONFIG_DIR}
)
##{GLOB 所有文件 | GLOB_RECURSE 递归查找文件&文件夹}
file(GLOB hw_drv_include_files ${PROJECT_SOURCE_DIR}/src/include/uapi/hw/armv7-m/*)
install(FILES
${hw_drv_include_files}
DESTINATION ${INSTALL_M4_CORTEX_INCLUDE_DIR}/hw/armv7-m
)
install(FILES
${PROJECT_SOURCE_DIR}/src/include/uapi/prt_clk.h
${PROJECT_SOURCE_DIR}/src/include/uapi/prt_cpup.h
${PROJECT_SOURCE_DIR}/src/include/uapi/prt_err.h
${PROJECT_SOURCE_DIR}/src/include/uapi/prt_errno.h
${PROJECT_SOURCE_DIR}/src/include/uapi/prt_event.h
${PROJECT_SOURCE_DIR}/src/include/uapi/prt_exc.h
${PROJECT_SOURCE_DIR}/src/include/uapi/prt_hook.h
${PROJECT_SOURCE_DIR}/src/include/uapi/prt_hwi.h
${PROJECT_SOURCE_DIR}/src/include/uapi/prt_idle.h
${PROJECT_SOURCE_DIR}/src/include/uapi/prt_mem.h
${PROJECT_SOURCE_DIR}/src/include/uapi/prt_module.h
${PROJECT_SOURCE_DIR}/src/include/uapi/prt_queue.h
${PROJECT_SOURCE_DIR}/src/include/uapi/prt_sem.h
${PROJECT_SOURCE_DIR}/src/include/uapi/prt_sys.h
${PROJECT_SOURCE_DIR}/src/include/uapi/prt_task.h
${PROJECT_SOURCE_DIR}/src/include/uapi/prt_tick.h
${PROJECT_SOURCE_DIR}/src/include/uapi/prt_timer.h
${PROJECT_SOURCE_DIR}/src/include/uapi/prt_typedef.h
DESTINATION ${INSTALL_M4_CORTEX_INCLUDE_DIR}/
)
endif()
@@ -0,0 +1,39 @@
################交叉编译#####################
#cross-compilation config
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CPU_TYPE "$ENV{CPU_TYPE}" )
set(PLAM_TYPE "$ENV{PLAM_TYPE}" )
set(LIB_TYPE "$ENV{LIB_TYPE}" )
set(SYSTEM "$ENV{SYSTEM}" )
set(CORE "$ENV{CORE}" )
set(LIB_RUN_TYPE "$ENV{LIB_RUN_TYPE}" )
set(BUILD_DIR "$ENV{BUILD_TMP_DIR}" ) #version id
set(OBJCOPY_PATH "$ENV{OBJCOPY_PATH}" ) #OBJCOPY_PATH
set(COMPILE_MODE "$ENV{COMPILE_MODE}" )
set(CC_TYPE "$ENV{CC_TYPE}" )
set(TOOLCHAIN_DIR "$ENV{HCC_PATH}") #该路径应该是外部传入,指向编译工具路径
##compiler specified in /etc/profile
set(CMAKE_C_COMPILER "${TOOLCHAIN_DIR}/arm-none-eabi-gcc" CACHE PATH "arm-gcc C compiler" FORCE)
set(CMAKE_ASM_COMPILER "${TOOLCHAIN_DIR}/arm-none-eabi-gcc" CACHE PATH "arm-gcc ASM compiler" FORCE)
if(${CPU_TYPE} STREQUAL "m4")
set(CMAKE_ASM_FLAGS "--specs=nosys.specs")
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -O2 -pipe ${STRONG_COMPILE_WARING_FLAG} ${COMPILE_WARING_FLAG} -std=gnu11 -fno-common -fomit-frame-pointer -mthumb -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -Wa,-mimplicit-it=thumb -fstack-protector-strong -funsigned-char <FLAGS> <INCLUDES> -c <SOURCE> -o <OBJECT>")
set(CMAKE_C_FLAGS "--specs=nosys.specs") #原ID形式\"888888\"
set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> -O2 -pipe ${STRONG_COMPILE_WARING_FLAG} ${COMPILE_WARING_FLAG} -std=gnu11 -fno-common -fomit-frame-pointer -mcpu=cortex-m4 -mthumb -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -fstack-protector-strong -fdata-sections -ffunction-sections -fshort-enums -funsigned-char -DSECUREC_BUFFER_SIZE=32 <FLAGS> <INCLUDES> -c <SOURCE> -o <OBJECT>")
endif()
set(CMAKE_LINKER "${TOOLCHAIN_DIR}/arm-none-eabi-ld" CACHE STRING "" FORCE)
set(CMAKE_AR "${TOOLCHAIN_DIR}/arm-none-eabi-ar" CACHE STRING "" FORCE)
set(CMAKE_C_LINK_FLAGS "-r ")
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> -r <TARGET> <OBJECTS>")
@@ -0,0 +1,34 @@
################交叉编译#####################
set(CPU_TYPE "$ENV{CPU_TYPE}" )
set(PLAM_TYPE "$ENV{PLAM_TYPE}" )
set(LIB_TYPE "$ENV{LIB_TYPE}" )
set(SYSTEM "$ENV{SYSTEM}" )
set(CORE "$ENV{CORE}" )
set(LIB_RUN_TYPE "$ENV{LIB_RUN_TYPE}" )
set(BUILD_DIR "$ENV{BUILD_TMP_DIR}" ) #version id
set(OBJCOPY_PATH "$ENV{OBJCOPY_PATH}" ) #OBJCOPY_PATH
set(COMPILE_MODE "$ENV{COMPILE_MODE}" )
set(HOME_PATH "$ENV{HOME_PATH}" )
set(COMPILE_OPTION "$ENV{COMPILE_OPTION}" )
set(RPROTON_INSTALL_FILE_OPTION "$ENV{RPROTON_INSTALL_FILE_OPTION}" )##RPROTON_INSTALL_FILE_OPTION="SUPER_BUILD";
#### 统一告警选项,请审慎增删
set(STRONG_COMPILE_WARING_FLAG "-Wunused -Wredundant-decls -Wfloat-conversion -Wwrite-strings -Wunused-macros -Wswitch-default -Wshift-overflow=2 -Wnested-externs -Wmissing-include-dirs -Wlogical-op -Wjump-misses-init -Wformat-security -Wvla -Wframe-larger-than=4096 -Wduplicated-cond -Wdisabled-optimization -Wduplicated-branches -Wignored-qualifiers -Wimplicit-fallthrough=3 -Wpointer-arith -Wshift-negative-value -Wsign-compare -Wtype-limits -Wcast-qual -Wundef -Wbad-function-cast -Wold-style-definition -Wpacked -Wstrict-prototypes -Wstack-usage=2048")
set(COMPILE_WARING_FLAG " -Wall -Werror -Wextra -Wformat=2 -Wfloat-equal -Wshadow -Wtrampolines -Wdate-time ")## -Wall -Werror -Wextra -Wformat=2 -Wfloat-equal
if (${CPU_TYPE} STREQUAL "m4" )
include(${HOME_PATH}/cmake/tool_chain/rtosk_tool_chain_gcc.cmake)
endif()
if (${COMPILE_OPTION} STREQUAL "coverity" OR ${COMPILE_OPTION} STREQUAL "fortify" )
set(CMAKE_C_COMPILER_WORKS TRUE)
set(CMAKE_CXX_COMPILER_WORKS TRUE)
set(CMAKE_ASM_COMPILER_WORKS TRUE)
endif()
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> -r -D <TARGET> <OBJECTS>")
+21
View File
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<config>
<version>1.0.0</version>
<UniProton_compile_mode>release</UniProton_compile_mode>
<tools>
<tool tool_name="cmake">
<tool_path>/opt/buildtools/cmake-3.20.5/bin</tool_path>
</tool>
</tools>
<projects>
<project cpu_type="m4">
<lib_type>SRE</lib_type>
<platform plat_name="cortex">
<name>cortex</name>
<compile_path_x86>/opt/buildtools/gcc-arm-none-eabi-10-2020-q4-major/bin</compile_path_x86>
<compile_path_arm64>/opt/buildtools/gcc-arm-none-eabi-10-2020-q4-major/bin</compile_path_arm64>
<kconf_dir>m4</kconf_dir>
</platform>
</project>
</projects>
</config>
+124
View File
@@ -0,0 +1,124 @@
# 一、Linux下的编译
## 1.1 搭建Linux编译环境
##### 【注】当前所有编译器的安装目录都在/opt/buidltools下,首先需要创建该目录并设置权限:mkdir -p /opt/buildtools && chmod -R 755 /opt/buildtools
## 软件要求
1. SUSE Linux Enterprise Server
2. python 3.4+
3. Cmake
4. GNU Arm Embedded Toolchain编译器,用于代码编译。
## 1.2 安装编译器&构建器
- #### 安装GNU Arm Embedded Toolchain编译器。
1. 下载编译器.
- 当前开源版本只涉及32位,官方下载地址为:[GNU Arm Embedded Toolchain编译器](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads),指定版本:10-2020-q4-major。
2. 解压编译器.
- 可以参考如下命令完成解压:
<br>
tar -xvf gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2 -C /opt/buildtools
## 1.3 安装Cmake
1. 通过官网进行下载[Cmake](https://cmake.org/download/),下载指定版本3.20.5
2. 以tar包模式举例说明:
- 通过命令进行解压:
- tar -xvf cmake-3.20.5-Linux-x86_64.tar.gz -C /opt/buildtools
## 1.4 安装Python
##### 下面以python3.8为例介绍安装方法。
1. 通过[官网下载python源码包](https://gitee.com/link?target=https%3A%2F%2Fwww.python.org%2Fftp%2Fpython%2F3.8.5%2FPython-3.8.5.tgz)。
2. 解压源码包。
- 参考如下命令完成解压,将压缩包名替换为实际下载的源码包名:
```
tar -xf Python-3.8.5.tgz
```
3. 检查依赖。
- 解压后进入到目录中,执行./configure命令以检查编译与安装python所需的依赖:
```
cd Python-3.8.5
./configure
```
- 如果没有报错就继续下一步操作,如果存在报错就根据提示安装依赖。
4. 编译&安装python。
```
sudo make
sudo make install
```
5. 检查python版本并正确链接python命令。
```
python --version
```
- 如果显示的不是刚刚安装的python版本,则需要执行以下命令来正确链接python命令。
- a. 获取python目录,例如对于python 3.8.5,执行如下命令。
```
which python3.8
```
- b. 链接python命令到刚刚安装的python包。
将以下命令中的 "python3.8-path" 替换为 "which python3.8" 命令执行后的回显路径:
```
cd /usr/bin && sudo rm python && sudo ln -s "python3.8-path" python
```
- c. 再次检查python版本。
```
python --version
```
## 1.5 安装pip包管理工具。
##### 如果pip命令不存在,可以下载pip源码包进行安装。pip依赖setuptools,如果setuptools不存在,也需要安装。
1. 源码包方式安装:
- 安装setuptools。
- 点击[setuptools源代码包下载地址](https://gitee.com/link?target=https%3A%2F%2Fpypi.org%2Fproject%2Fsetuptools%2F),可以参考下面的命令进行安装:
```
sudo unzip setuptools-50.3.2.zip
cd setuptools
sudo python setup.py install
```
2. 安装pip。
- 点击[pip源代码包下载地址](https://gitee.com/link?target=https%3A%2F%2Fpypi.org%2Fproject%2Fpip%2F),可以参考下面的命令进行安装:
```
sudo tar -xf pip-20.2.4.tar.gz
cd pip-20.2.4
sudo python setup.py install
```
## 1.6 Linux下编译流程
##### 参照上述步骤完成环境搭建后,即可按以下步骤完成编译。
1. 下载UniProton代码
- git clone https://gitee.com/openeuler/UniProton.git
2. 下载libboundscheck, 按照[指导](../platform/README.md)操作
3. 执行编译
- 进入到UniProton根目录下执行命令即可
```
python build.py m4
```
# 二、提供镜像,用户自行下载
1. 在虚拟机操作命令:
`docker pull swr.cn-north-4.myhuaweicloud.com/openeuler-embedded/uniproton:v001`
- 执行完成之后,创建容器并进入(默认挂载当前执行命令的目录为容器内的/home/uniproton目录)
`docker run -it -v $(pwd):/home/uniproton swr.cn-north-4.myhuaweicloud.com/openeuler-embedded/uniproton:v001`
2. 下载代码
- 下载UniProton代码
`git clone https://gitee.com/openeuler/UniProton.git`
- 下载libboundscheck, 按照[指导](../platform/README.md)操作
3. 执行编译
- 进入到UniProton根目录下执行命令即可
```
python build.py m4
```
# 三、 编译结果
生成的静态库文件存放在output/UniProton/lib/cortex_m4目录下。
+770
View File
@@ -0,0 +1,770 @@
# UniProton 代码&文档贡献指南
- [编程规范](#编程规范)
- [总体原则](#总体原则)
- [目录结构](#目录结构)
- [命名](#命名)
- [排版与格式](#排版与格式)
- [注释](#注释)
- [](#宏)
- [头文件](#头文件)
- [数据类型](#数据类型)
- [变量](#变量)
- [函数](#函数)
- [可移植性](#可移植性)
- [业界编程规范](#业界编程规范)
- [文档写作规范](#文档写作规范)
- [Commit message规范](#Commitmessage规范)
- [贡献流程](#贡献流程)
- [协议](#协议)
- [加入我们](#加入我们)
<h2 id="编程规范">编程规范</h2>
此编程规范在业界通用的编程规范基础上进行了整理,供开发者参考使用。
### 总体原则
- 清晰,易于维护、易于重构。
- 简洁,易于理解,并且易于实现。
- 风格统一,代码整体风格保持统一。
- 通用性,遵循业界通用的编程规范。
### 目录结构
建议将工程按照功能模块划分子目录(可参考UniProton的功能模块划分),子目录再定义头文件和源文件目录。
### 命名
- 使用驼峰风格进行命名,此风格大小写字母混用,不同单词间通过单词首字母大写来分开,具体规则如下:
| 类型 | 命名风格 | 形式 |
| --------------------------- | -------------------------------- | ------------------------- |
| 函数,自定义的类型 | 大驼峰,或带有模块前缀的大驼峰 | AaaBbb, XXX_AaaBbb |
| 局部变量,函数参数,宏参数,结构体成员,联合体成员 | 小驼峰 | aaaBbb |
| 全局变量 | 带'g_'前缀的小驼峰 | g_aaaBbb |
| 宏,枚举值 | 全大写并下划线分割 | AAA_BBB |
| 内核头文件中防止重复包含的宏变量 | 带'PRT'前缀和'H'后缀,中间为大写模块名,以下划线分割 | PRT_MODULE_H |
- 全局函数、全局变量、宏、类型名、枚举名的命名,应当准确描述并全局唯一。
- 在能够准确表达含义的前提下,局部变量,或结构体、联合体的成员变量,其命名应尽可能简短。
- UniProton的对外API使用PRT_\<Module\>\<Func\>的方式,如果有动词和宾语,则采用PRT_\<Module\>\<Verb\>\<Object\>,比如:
```
PRT_TaskCreate
PRT_SemPend
PRT_TickGetCount
PRT_TaskGetStatus
```
kernel目录下内部模块间接口使用Os\<Module\>\<Func\>的方式,比如:
```
OsTaskScan
OsSwTmrCtrlInit
```
### 排版与格式
- 程序块采用缩进风格编写,使用空格而不是制表符('\t')进行缩进,每级缩进为4个空格。
- 采用K&R风格作为大括号换行风格,即函数左大括号另起一行放行首,并独占一行,其他左大括号跟随语句放行末,
右大括号独占一行,除非后面跟着同一语句的剩余部分,如if语句的else/else if或者分号,比如:
```c
struct MyType { // 左大括号跟随语句放行末,前置1个空格
...
}; // 右大括号后面紧跟分号
```
```c
int Foo(int a)
{ // 函数左大括号独占一行,放行首
if (a > 0) { // 左大括号跟随语句放行末,前置1个空格
...
} else { // 右大括号、"else"、以及后续的左大括号均在同一行
...
} // 右大括号独占一行
...
}
```
- 条件、循环语句使用大括号,比如:
```c
if (objectIsNotExist) { // 单行条件语句也加大括号
return CreateNewObject();
}
```
```c
while (condition) {} // 即使循环体是空,也应使用大括号
```
```c
while (condition) {
continue; // continue表示空逻辑,使用大括号
}
```
- case/default语句相对switch缩进一层,缩进风格如下:
```c
switch (var) {
case 0: // 缩进一层
DoSomething1(); // 缩进一层
break;
case 1:
DoSomething2();
break;
default:
break;
}
```
- 一行只写一条语句。
- 一条语句不能过长,建议不超过120个字符,如不能缩短语句则需要分行写。
- 换行时将操作符留在行末,新行进行同类对齐或缩进一层,比如:
```c
// 假设下面第一行不满足行宽要求
if (currentValue > MIN && // 换行后,布尔操作符放在行末
currentValue < MAX) { // 与(&&)操作符的两个操作数同类对齐
DoSomething();
...
}
```
```c
// 假设下面的函数调用不满足行宽要求,需要换行
ReturnType result = FunctionName(paramName1,
paramName2,
paramName3); // 保持与上方参数对齐
```
```c
ReturnType result = VeryVeryVeryLongFunctionName( // 写入第1个参数后导致过长,直接换行
paramName1, paramName2, paramName3); // 换行后,4空格缩进一层
```
```c
// 每行的参数代表一组相关性较强的数据结构,放在一行便于理解,此时可理解性优先于格式排版要求
int result = DealWithStructLikeParams(left.x, left.y, // 表示一组相关参数
right.x, right.y); // 表示另外一组相关参数
```
- 声明定义函数时,函数的返回类型以及其他修饰符,与函数名同行。
- 指针类型"*"应该靠右跟随变量或者函数名,比如:
```c
int *p1; // Good:右跟随变量,和左边的类型隔了1个空格
int* p2; // Bad:左跟随类型
int*p3; // Bad:两边都没空格
int * p4; // Bad:两边都有空格
```
当"*"与变量或函数名之间有其他修饰符,无法跟随时,此时也不要跟随修饰符,比如:
```c
char * const VERSION = "V100"; // Good:当有const修饰符时,"*"两边都有空格
int Foo(const char * restrict p); // Good:当有restrict修饰符时,"*"两边都有空格
```
- 根据上下内容的相关程度,合理安排空行,但不要使用连续3个或更多空行。
- 编译预处理的"#"统一放在行首,无需缩进。嵌套编译预处理语句时,"#"可以进行缩进,比如:
```c
#if defined(__x86_64__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) // 位于行首,不缩进
#define ATOMIC_X86_HAS_CMPXCHG16B 1 // 缩进一层,区分层次,便于阅读
#else
#define ATOMIC_X86_HAS_CMPXCHG16B 0
#endif
```
### 注释
- 注释的内容要清楚、明了,含义准确,防止注释二义性。
- 在代码的功能、意图层次上进行注释,即注释解释代码难以直接表达的意图,而不是仅仅重复描述代码。
- 函数声明处注释描述函数功能、性能及用法,包括输入和输出参数、函数返回值、可重入的要求等;定义处详细描述函数功能和实现要点,如实现的简要步骤、实现的理由、设计约束等。
- 全局变量要有较详细的注释,包括对其功能、取值范围以及存取时注意事项等的说明。
- 避免在注释中使用缩写,除非是业界通用或子系统内标准化的缩写。
- 文件头部要进行注释,建议注释列出:版权说明、版本号、生成日期、作者姓名、功能说明、与其它文件的关系、修改日志等。
- 注释风格要统一,建议优先选择/* */的方式,注释符与注释内容之间要有1空格,单行、多行注释风格如下:
```c
/* 单行注释 */
```
```c
/*
* 多行注释
* 第二行
*/
```
- 注释应放在其代码上方或右方。
上方的注释,与代码行之间无空行,保持与代码一样的缩进。
右边的注释,与代码之间至少相隔1个空格。如果有多条右置注释,上下对齐会更加美观,比如:
```c
#define A_CONST 100         // 此处两行注释属于同类
#define ANOTHER_CONST 200   // 可保持左侧对齐
```
### 宏
- 代码片段使用宏隔离时,统一通过#ifdef的方式,例如:
```c
#ifdef PRTCFG_XXX
...
#endif
```
- 定义宏时,要使用完备的括号,比如:
```c
#define SUM(a, b) a + b     // 不符合本条要求
#define SUM(a, b) ((a) + (b)) // 符合本条要求
```
但是也要避免滥用括号,比如单独的数字或标识符加括号毫无意义:
```c
#define SOME_CONST 100         // 单独的数字无需括号
#define ANOTHER_CONST   (-1)    // 负数需要使用括号
#define THE_CONST   SOME_CONST  // 单独的标识符无需括号
```
- 包含多条语句的函数式宏的实现语句必须放在do-while(0)中,例如:
```c
#define FOO(x) do { \
(void)printf("arg is %d\n", (x)); \
DoSomething((x)); \
} while (0)
```
- 禁止宏调用参数中出现预编译指令。
- 宏定义不以分号结尾。
### 头文件
- 设计原则
- 头文件应当职责单一。
- 一个模块通常包含多个.c文件,建议放在同一个目录下,目录名即为模块名;如果一个模块包含多个子模块,则建议每一个子模块提供一个对外的.h,文件名为子模块名。
- 建议每一个.c文件应有一个同名.h文件,用于声明需要对外公开的接口。
- 头文件中适合放置接口的声明,不适合放置实现。
- 不要在头文件中定义变量。
- 禁止头文件循环依赖,循环依赖指a.h包含b.h,b.h包含c.hc.h包含a.h。
- 头文件应当自包含,即任意一个头文件均可独立编译,但同时也要避免包含用不到的头文件。
- 头文件必须用#define保护,防止重复包含,比如内核中统一使用以下宏定义保护:
```c
#ifndef PRT_<MODULE>_H // 比如 PRT_TASK_H
#define PRT_<MODULE>_H
...
#endif
```
- 禁止通过声明的方式引用外部函数接口、变量,只能通过包含头文件的方式使用其他模块或文件提供的接口。
- 禁止在 extern "C" 中包含头文件。
- 按照合理的顺序包含头文件:
1) 源文件对应的头文件
2) C标准库
3) 需要包含的OS其他头文件
- 版权声明
- 头文件版权声明一致,放在头文件置顶位置。
- 如果提交的代码是在开源软件基础上修改所编写或衍生的代码,请遵循开源许可协议要求,并且已履行被修改软件的许可证义务。
### 数据类型
基础类型定义统一使用prt_typedef.h中定义的类型,比如定义无符号32位整型变量使用U32。
### 变量
- 一个变量只有一个功能,不要把一个变量用作多种用途。
- 防止局部变量与全局变量同名。
- 不用或者少用全局变量。
- 定义函数的局部变量时,控制变量的占用空间,避免因占用过多栈空间导致程序运行失败。比如需要一个大数组,可以通过动态分配内存的方式来避免栈空间占用过大。
- 在首次使用前初始化变量。
- 指向资源句柄或描述符的变量,在资源释放后立即赋予新值,包括指针、文件描述符以及其它指向资源的变量。
- 禁止将局部变量的地址返回到其作用域以外,下面是一个**错误示例:**
```c
int *Func(void)
{
int localVar = 0;
...
return &localVar; // 错误
}
void Caller(void)
{
int *p = Func();
...
int x = *p; // 程序产生未定义行为
}
```
**正确代码示例:**
```c
int Func(void)
{
int localVar = 0;
...
return localVar;
}
void Caller(void)
{
int x = Func();
...
}
```
- 如果要使用其他模块的变量,应尽量避免直接对变量进行访问,而是通过统一的函数封装或者宏封装的方式,比如mutex模块中:
```c
// 私有头文件中引入全局变量,但要避免直接使用
extern struct TagQueCb *g_allQueue;
// 通过GET_QUEUE_HANDLE的方式对g_allQueue进行访问
#define GET_QUEUE_HANDLE(queueId) (((struct TagQueCb *)g_allQueue) + (queueId))
```
### 函数
- 重复代码应该尽可能提炼成函数。
- 避免函数过长,新增函数不超过 40-50 行。
- 内联函数要尽可能短,避免超过 10 行(非空非注释)。
- 避免函数的代码块嵌套过深。
- 函数应避免使用全局变量、静态局部变量和I/O操作,不可避免的地方应集中使用。
### 可移植性
不使用与硬件或操作系统关系很大的语句,而使用建议的标准语句,以提高软件的可移植性和可重用性。
### 业界编程规范
C语言编程规范参考资料较多,大家可以自行了解,本文不再过多赘述。
<h2 id="文档写作规范">文档写作规范</h2>
UniProton欢迎开发者参与到开源社区的贡献中来,本文主要介绍参与UniProton文档贡献的写作规范,如果贡献者提交文档的修改或提交新的文档,请参照此规范。
### 命名规范
如需提交新的文档,在<a href="https://gitee.com/openeuler/UniProton" target="_blank">UniProton代码仓</a>doc目录下创建新的.md文件,命名需遵循 xxx\_xxx.md 格式,根据文档的内容来声明。
比如介绍写作规范的文档,可以命名为 UniProton\_doc\_write\_standard.md。
### 内容规范
以简洁、直观地表达所述内容为目的,介绍性文档言简意赅介绍原理、架构、设计思路等,操作类文档写明关键步骤,以便能对其他开发者起到帮助。可以优先使用中文,建议中英文都支持,UniProton也将持续更新,保证中英文的同步。
1. **标题**
建议标题层级不超过三级。
2. **正文**
- 操作类文档以移植为例,文档结构可以参考如下:
1. 目的(简述操作目的,如移植到哪款型号的单板)
2. 软硬件环境准备
3. 移植具体步骤
4. 结果验证
- 介绍性文档以开发指南某一功能为例,文档结构可以参考如下:
1. 概述(概念及原理介绍)
2. 功能(支持的接口列表)
3. 开发流程(如何使用及相应步骤)
4. 编程实例(提供具体代码示例)
5. 注意事项
6. 其他
3. **图片**
图片统一存放到文档同级目录下的images文件夹中(英文文档对应images-en),如 UniProton/doc/getting\_started.md 中使用的图片,统一放置到 UniProton/doc/images 目录下,文档中使用相对路径引用图片。图片建议根据内容命名,只用数字序列不利于后续图片的继承。
<!--
>![](public_sys-resources/icon-note.gif) **说明:**
>引用方式:
>!\[\]\(./images/images-standard.png\)
-->
**说明:** 图
如果是自制图片,配色请参考如下,格式不限,png/jpg/gif...均可,如果是截图或者其他地方引用图片,风格不做限制。
<!--
![](images/contribute/picture_color_in_document_writing.png)
-->
**说明:** 图
4. **表格**
在md文件中可以按照如下形式插入表格。
```
| Tables | Type | Note |
| ----------- |:-------------:| -----:|
| first | standard | None |
| second | outstanding | 5 |
| third | inside | with |
```
5. **代码**
正文中插入代码段,可以在段落前后加上符号 \`\`\`。
<blockquote>
```c
int size = 10;
\```
</blockquote>
<h2 id="Commitmessage规范">Commit message规范</h2>
### 概要说明
目前,社区有多种 Commit message 的写法规范。UniProton采用的是Angular规范,这是目前使用最广的写法,比较合理和系统化,并且有配套的工具。
### Commit message的作用
格式化的Commit message有几个好处:
- 提供更多的历史信息,方便快速浏览
- 可以过滤某些commit(比如文档改动),便于快速查找信息
- 可以直接从commit生成Change log
### UniProton Commit message的格式
每次提交,Commit message 都包括三个部分:HeaderBody 和 Footer。
```
<header>
空一行
<body>
空一行
<footer>
```
比如:
```
fix(stm32f411): fix stm32f411 migration guide file error
fix some error in stm32f411re migration guide file.
Close #75
```
- **Header格式**
Header部分只有一行,格式为:
```
<type>(<scope>): <subject>
```
Header部分共包括三个字段:type(必需)、scope(可选)和subject(必需)。
- type
type用于说明 commit 的类别,只允许使用下面7个标识。
```
feat:feature的缩写,表示这是一个新功能
fix:修补bug
docsdocumentation的缩写,表示修改的是文档
style: 格式修改,是不影响代码运行的变动
refactor:重构,它即不是新增功能,也不是修改bug
test:增加测试
chore:构建过程或辅助工具的变动
```
- scope
scope用于说明 commit 影响的范围,比如对UniProton Kernel的base的修改会影响全部代码,所以填写all。如果只修改STM32F411的代码,则填写STM32F411。
- subject
subject用于简短描述 commit 目的,不超过50个字符。subject以动词开头,使用第一人称现在时,比如change,而不是changed或changes。subject的第一个字母小写,结尾不加英文句号(.)。
- **Body格式**
Body 部分是对本次 commit 的详细描述,可以分成多行,下面是一个范例。
```
Add porting contest board projects to UniProton
Board list:
Arduino-M0-PRO
ATSAM4S-XPRO
ATSAMD21-XPRO
EFM32-SLSTK3400A
EFM32-SLSTK3401A
EFM32-STK3700
FRDM-KL26Z
FRDM-KW41Z
```
有两个注意点:
- 使用第一人称现在时,比如使用change而不是changed或changes。
- 应该说明代码变动的动机,以及与以前行为的对比。
- **Footer格式**
Footer 部分只用于两种情况。
- 不兼容变动
如果当前代码与上一个版本不兼容,则 Footer 部分以BREAKING CHANGE开头,后面是对变动的描述、以及变动理由和迁移方法。
```
BREAKING CHANGE: isolate scope bindings definition has changed.
To migrate the code follow the example below:
Before:
scope: {
myAttr: 'attribute',
}
After:
scope: {
myAttr: '@',
}
The removed `inject` wasn't generaly useful for directives so there should be no code using it.
```
- 关闭 Issue
如果当前 commit 针对某个issue,那么可以在 Footer 部分关闭这个 issue 。
```
Closes #16, #24, #92
```
### 更多参考
更详细的commit规则请参考原始的规范说明:<a href="https://github.com/mychaser/docgather/blob/master/GitCommitMessageConventions.pdf" target="_blank">Angular规范</a>。
<h2 id="贡献流程">贡献流程</h2>
UniProton的代码仓托管在gitee上,因此代码贡献者需要在gitee上注册账号才能贡献代码。注册账号可以参考<a href="https://gitee.com/help/articles/4113#article-header0" target="_blank">注册Gitee账号</a>。
代码贡献可以分为**在线修改**和**本地提交**两种。
### 方法一:在线修改
在线修改适用于修改量较少的情况,方便快捷,点击页面“编辑”按钮,跳转到对应的编辑页面。
<!--
![](./images/contribute/gitee_online_edit.png)
-->
**说明:** 图
编辑修改后,点击页面下方“提交”按钮,即提交修改到 UniProton 工程,静候工作人员审核即可。
<!--
![](./images/contribute/gitee_online_submit.png)
-->
**说明:** 图
### 方法二:本地提交
本地提交适用于修改量较大的情况,主要说明如何参与UniProton开源代码贡献。进行UniProton的代码贡献可以遵循以下流程:
1. 下载Git工具。
2. 配置SSH公钥。
3. 配置本地Git账户信息。
4. fork UniProton源代码。
5. 同步UniProton仓库代码到fork的仓库。
6. 提交本地修改到fork的仓库。
7. 提交Pull Request到UniProton官方主仓库。
8. 查看Pull Request的状态。
#### **1 下载Git工具**
请至<a href="https://git-scm.com/download" target="_blank">git官网下载</a>,安装方法可以参考<a href="https://gitee.com/help/articles/4106#article-header0" target="_blank">Git的安装</a>。
#### **2 配置SSH公钥**
1\) 先查看本地是否有公钥。如果存在公钥,则返回类似如下显示的一对文件,一般文件名为 id\_rsa 和 id\_rsa.pub,其中 .pub 后缀的文件是公钥,另一个文件是密钥。
```
$ ls ~/.ssh
id_rsa id_rsa.pub
```
如果系统内没有公钥文件,可以执行如下命令生成,公钥文件一般默认存放在 \~/.ssh路径下:
```
$ ssh-keygen -t rsa -C "your-email@youremail.com" //其中的邮箱为注册gitee账户时使用的邮箱
```
2\) 配置gitee账户的SSH公钥,参考<a href="https://gitee.com/help/articles/4191#article-header0" target="_blank">gitee上SSH公钥设置</a>。
#### **3 配置本地Git账户信息**
账户信息即用户名和邮箱,注意此处的用户名和邮箱指的是注册gitee账户所使用的账户名和邮箱。配置以后,每次Git提交都会使用该信息:
```
$ git config --global user.name "your-username"
$ git config --global user.email "your-email@youremail.com"
```
如果本地pc上已经存储了账户信息,可以在“控制面板-\>用户帐户-\>凭据管理器”中确认保存的gitee账号密码是否正确,如果错误会导致无法提交修改到远程仓库。如果无法在本地pc上确认或修改为正确的账号信息,可以执行如下命令,不使用本地pc中保存的账号密码:
```
$ git config --global --unset credential.helper
```
查看git的所有配置信息,可以使用如下命令:
```
$ git config --list
```
#### **4 fork UniProton源代码**
1\) 使用个人gitee账号登陆gitee。
2\) 进入UniProton官方主仓库(master分支):<a href="https://gitee.com/openeuler/UniProton" target="_blank">UniProton源码仓</a>。
3\) 点击右上角fork按钮,将UniProton的代码fork到个人账号下,在弹出的窗口中选择要fork到的个人账号,点击确认后,稍等一会就会自动跳转到刚刚fork出来的个人账号下的UniProton仓库。
<!--
![](./images/contribute/gitee_fork.png)
**说明:** 图
-->
#### **5 同步UniProton仓库代码到fork的仓库**
开发代码前,首先需要确保当前个人账号下的UniProton代码和UniProton官方仓库是一致的。 因为从fork代码到现在,UniProton官方仓库可能已经更新了内容,所以开发代码前需要先同步UniProton仓库代码到fork的仓库。如果仓库刚刚fork,可以跳过此步。
<!--
![](./images/contribute/gitee_fork4.png)
**说明:** 图
-->
点击上图中红框中的按钮从UniProton官方仓库拉取代码到个人账号fork的仓库,此时会弹出一个对话框以确定同步动作,如下图所示:
<!--
![](./images/contribute/gitee_fork5.png)
**说明:** 图
-->
点击确定后,gitee就会开始同步代码,用户无需再做其他操作。
#### **6 提交本地修改到fork的仓库**
1\) 开发的第一步,是clone代码到本地pc。
```
git clone https://gitee.com/gitee账户名/UniProton.git //个人账号fork的仓库地址,clone下来后仓库名默认为origin
```
基于UniProton的远程master分支,创建并切换到本地分支,例如本地分支名也是master:
```
git checkout -b master origin/master
```
2\) 在本地分支上进行开发。开发完成之后,git add 添加代码到本地仓库,并git commit 提交到本地仓库,具体commit信息的填写规范,请参考[Commit message规范](#Commitmessage规范)。
3\) 执行git push origin master操作,将代码提交到gitee上自己个人账号的master分支。
**说明:** 所有git命令相关操作,如果不熟悉,请自行上网查找。
#### **7 提交Pull Request到UniProton官方主仓库**
通过上述步骤,修改已经提交到个人远程仓库中,此时就可以向UniProton官方主仓库master分支提交Pull Request,该操作在gitee网页上进行。
1\) 进入个人账号下fork的UniProton仓库首页,点击下图红框中的“+ Pull Request”。
<!--
![](./images/contribute/gitee_fork6.png)
**说明:**
-->
2\) 之后gitee会跳转到创建Pull Request的详细页面,并给出对应的源分支和要修改的目标分支,目标分支为UniProton官方主仓库master分支,如下图。
<!--
![](./images/contribute/gitee_fork7.png)
**说明:**
-->
如果代码没有冲突则会显示下图红框中“可自动合并”的提示,否则需要先解决冲突然后再重新创建Pull Request。在线解决代码冲突可以参考<a href="https://gitee.com/help/articles/4305" target="_blank">在线解决代码冲突</a>。
<!--
![](./images/contribute/gitee_fork8.png)
**说明:**
-->
填入Pull Request的标题和说明,点击“创建”,就可以提交一个Pull Request。右边的审查人员、测试人员、里程碑、标签、优先级是可选项,不选择也不影响Pull Request的创建。
<!--
>![](public_sys-resources/icon-note.gif)
**说明:**
-->
**说明:**
>- 如果提交的代码是为了解决issue问题,记得将issue和此次代码提交相关联,关联方法请参考<a href="https://gitee.com/help/articles/4141" target="_blank">Commit关联Issue</a>和<a href="https://gitee.com/help/articles/4142" target="_blank">Pull Request关联Issue</a>。
>- 如果提交的Pull Request中有新增意见,需要在评论里回复,并@提意见的人说明已经解决
#### **8 查看Pull Request的状态**
1\) 进入<a href="https://gitee.com/openeuler/UniProton" target="_blank">UniProton主仓库</a>首页。
2\) 点击下图中的“Pull Requests”,可以看到当前UniProton主仓库上所有的Pull Request。
<!--
![](./images/contribute/gitee_pr.png)
**说明:**
-->
“开启的”表示这个Pull Request的代码还没有合入,“已合并”表示这个Pull Request的代码已经合入,“已关闭”表示这个Pull Request虽然已经关闭但是代码没有被合入。
现在就静候UniProton主仓库管理员review代码吧,验证ok就会合入修改,恭喜您成为Contributor,感谢您为开源社区做出的贡献。
<h2 id="协议">协议</h2>
### 知识共享许可协议
**您可以自由地:**
**分享** — 在任何媒介以任何形式复制、发行本文档。
**演绎** — 修改、转换或以本文档为基础进行创作。
只要你遵守许可协议条款,许可人就无法收回你的这些权利。
**惟须遵守下列条件:**
**署名** — 您必须提供适当的证书,提供一个链接到许可证,并指示是否作出更改。您可以以任何合理的方式这样做,但不是以任何方式表明,许可方赞同您或您的使用。
**非商业性使用** — 您不得将本文档用于商业目的。
**相同方式共享** — 如果您的修改、转换,或以本文档为基础进行创作,仅得依本素材的授权条款来散布您的贡献作品。
**没有附加限制** — 您不能增设法律条款或科技措施,来限制别人依授权条款本已许可的作为。
**声明:**
当您使用本素材中属于公众领域的元素,或当法律有例外或限制条款允许您的使用,则您不需要遵守本授权条款。
未提供保证。本授权条款未必能完全提供您预期用途所需要的所有许可。例如:形象权、隐私权、著作人格权等其他权利,可能限制您如何使用本素材。
<!--
>![](public_sys-resources/icon-notice.gif)
说明:图
-->
**须知:**
>为了方便用户理解,这是协议的概述。您可以访问网址http://license.coscl.org.cn/MulanPSL2/index.html 了解完整协议内容。
### 知识产权政策
1. 定义
**1.1 关联公司:** 是指就一个实体而言,该实体直接或间接控制的另一实体,或者,直接或间接控制该实体的另一实体,或者与该实体被某一实体共同控制的其他实体;这里的“控制”是指直接或间接拥有一个实体中多于50%份额的投票权或表决权或者以任何其他方式直接或间接控制该实体50%以上的具有该实体决策权的所有者权益。
**1.2 遵从软件:** 是指由华为技术有限公司(后称“华为”)正式发布且未经过修改的UniProton,或者虽经修改,但能通过认证测试的UniProton。
**1.3 认证测试:** 是指为了确保UniProton与其一起使用的软件或硬件的兼容性和接口一致性而由华为开发的测试。认证测试套件及相关要求和指导将在UniProton官网公布。
**1.4 贡献:** 是指由任何人提交给UniProton将其纳入或建议纳入UniProton中的任何信息或资料,包括软件源代码,文档或相关材料。
**1.5 贡献者:** 是指提交贡献给UniProton的人。
**1.6 您:** 是指任何个人,公司,合作企业,共同控股公司,有限合伙,协会,有限责任公司或企业或实体。
**1.7 UniProton** 是指由华为主导开发、管理、并由华为在openEuler官网上发布的可用于芯片,嵌入式领域的轻量开源操作系统项目。华为可能会对该软件不断进行更新。
**1.8 承诺的专利权利要求:** 是指专利或专利申请的一个或多个权利要求,且满足如下条件:(i)由贡献者或其关联公司现在或将来拥有控制的,或其他有权许可且无需向无关联的第三方支付费用的,且(ii)会因接受者制造,使用,许诺销售,销售,进口或以其他方式转移贡献者提交给UniProton的贡献单独或将该贡献与前述UniProton的结合所必然且直接侵犯。
**1.9 政策:** 是指本UniProton知识产权政策。
**1.10 接收者:** 是指接受本政策并享有本政策下许可的个人或法律实体。
**1.11 承诺者:** 是指贡献者及其关联公司。
2. 许可
UniProton的代码将以MulanPSL2 License,除非华为另选其他许可证 (“可适用的许可证”)。接收者可以访问 [http://license.coscl.org.cn/MulanPSL2/index.html](http://license.coscl.org.cn/MulanPSL2/index.html)查看该许可证的详细内容。
3. 专利不诉承诺
3.1 在接收者遵守本政策的前提下,每个承诺者许诺不对任何接收者就其制造,使用,许诺销售,销售,进口或以其他方式转移遵从软件的行为发起指控,诉讼或其他法律程序指控其侵犯该承诺者的承诺专利权利主张。前述承诺不适用于因以下原因引起的侵犯承诺专利权利主张的指控:i. 由其他方提交的贡献;ii 承诺者贡献代码后其他人对该贡献的修改;iii 该贡献与硬件的结合或者与不属于贡献所针对的UniProton的其他代码的结合;或者 iv 不属于遵从软件的软件。前述承诺也不适用于集成在个人便携产品(如手机,便携电脑,可穿戴设备等)中的遵从软件。
3.2 这是每个承诺者对接收者的个人承诺。
3.3 每个承诺者理解并同意专利不诉承诺是具有法律约束力且不可撤回的(根据第4条撤回的除外),而且对该承诺者、其继受者、受让方以及有权对第三方实施该承诺专利主张的任何独占被许可人都是有约束力的。
4. 终止许可及专利不诉承诺的权利
在满足可适用许可证规定的前提下,如果贡献者或其关联公司向其他基于第3条享有专利不诉承诺权益且未根据本条终止的接收者发起指控,诉讼或其他法律程序,指控其制造,使用,许诺销售,销售,进口或者以其他形式转移遵从软件构成对其专利直接侵权或帮助侵权的,那么该接收者及其关联公司本政策下所有的许可以及专利不诉承诺将立即终止。
5. 无其他权利
5.1 本政策并不授予接收者使用华为的贸易名称,商标,服务标记或产品名称的许可。
5.2 除本政策和可使用许可证明确约定外,没有其他明示或默示的专利,商标,版权或其他知识产权的许可授予接收者,不论是通过默示,放弃,禁止反言或其他形式。
6. 无担保
除非适用法强制规定或者双方有明确书面约定, UniProton, 遵从软件以及任何贡献均如是提供,无任何形式的担保,不论是明示还是默示,包括但不限于不侵权,适销性或满足特定目的的担保。
7. 责任限制
除非适用法强制规定,在任何情况下,不论是基于侵权,合同或其他,华为及其关联公司或任何贡献者均不对其他贡献者,接收者或第三方因本政策或因使用或未能使用华为发布的UniProton或者对UniProton的任何贡献导致的损失,包括任何直接的,间接的,特别的,偶然的损失或者数据丢失等,即使该方已经被建议该种可能的损失。
8. 可分离性
如果本政策内的任何条款被认定为无效,不可实施或者与适用法冲突,本政策中的其他条款继续有效。
9. 修改
华为有权自行决定修改本政策。该修改后的政策从其在UniProton官网上公布之日起生效,并仅适用于同时或此后发布的UniProton软件版本。
10. 适用法和争议解决
本政策适用中华人民共和国法律。任何因本政策引起或与本政策相关的纠纷应提交到北京中国国际经济贸易仲裁委员会。该仲裁裁决是终局的并对仲裁双方具有法律约束力。
<h2 id="联系我们">联系我们</h2>
* 技术支持
欢迎<a href="https://gitee.com/openeuler/UniProton/issues" target="_blank">提交issue</a>对关心的问题发起讨论,欢迎到<a href="https://bbs.huaweicloud.com/" target="_blank">UniProton论坛</a>交流。
您也可以发送问题至邮箱UniProtonSupport@huawei.com。
* 参与贡献
如您有兴趣参与开源贡献,欢迎提交PR参与特性建设,可至<a href="https://gitee.com/openeuler/UniProton " target="_blank">UniProton gitee源码仓</a>下载开源代码。
* 技术合作
如您有合作意向,希望加入UniProton生态合作伙伴,请发邮件至UniProtonSupport@huawei.com,或访问<a href="https://www.openeuler.org/zh/" target="_blank">openEuler官网</a>,进一步了解详细信息。
+39
View File
@@ -0,0 +1,39 @@
## 系统架构
UniProton系统由Mem、Arch、Kernel、IPC、OM五大子系统构成,Mem、Arch是整个系统的基石。
各子系统的职责如下:
- Mem:实现内存分区的创建,内存块的申请和释放等功能。
- Arch:实现和芯片强相关的硬件特性功能,如硬中断、异常接管等。
- Kernel:实现任务、软中断、TICK中断、软件定时器等功能。
- IPC:实现事件、队列、信号量等功能。
- OM:实现cpup、hook等调测功能。
## 代码目录结构说明
| 一级目录 | 二级目录 | 三级目录 | 说明 |
| ------- | -------- | -------- | -------------------------|
| build | uniproton_ci_lib | | 编译框架的公共脚本 |
| | uniproton_config | config_m4 | cortex_m4芯片的功能宏配置文件 |
| cmake | common | build_auxiliary_script | 转换Kconfig文件为buildef.h脚本 |
| | functions | | cmake的公共功能函数 |
| | tool_chain | | 编译器和编译选项配置文件 |
| doc | | | 项目配置、规范、协议等文档 |
| | design | | UniProton系统架构和特性说明 |
| platform | | | libboundscheck使用说明 |
| | libboundscheck | | libboundscheck预留目录,用户将下载的源码放在此目录下 |
| src | arch | cpu | cpu对应架构的功能适配代码 |
| | | include | cpu对应架构的头文件 |
| | config | | 用户main函数入口 |
| | | config | 用户配置功能宏开关 |
| | core | ipc | 事件、队列、信号量等功能 |
| | | kernel | 任务、中断、异常、软件定时器等功能 |
| | include | uapi | 对外头文件 |
| | mem | | 内存管理基本功能 |
| | | fsc | 内存管理FSC算法代码 |
| | | include | 内存管理头文件 |
| | om | cpup | cpu占用率统计功能 |
| | | err | 错误处理功能 |
| | | hook | 钩子函数功能 |
| | | include | 系统管理头文件 |
| | security | rnd | 随机化功能 |
| | utility | lib | 公共库函数 |
+60
View File
@@ -0,0 +1,60 @@
## CPU占用率介绍
### 什么是系统CPU占用率
系统CPU占用率(CPU Percent)是指周期时间内系统的CPU占用率,用于表示系统一段时间内的闲忙程度,也表示CPU的负载情况。系统CPU占用率的有效表示范围为0~10000,其精度为万分比。10000表示系统满负荷运转。
### 为什么需要系统CPU占用率
系统CPU占用率表示系统的负载情况,用户可以通过查看系统的负载,控制某些业务的流量以达到提高系统使用效率的目的。
### 什么是线程CPU占用率
线程CPU占用率指单个线程的CPU占用率,用于表示单个线程在一段时间内的闲忙程度。线程CPU占用率的有效表示范围为0~10000,其精度为万分比。10000表示在一段时间内系统一直在运行该线程。单核系统所有线程(包括中断和空闲任务)的CPUP之和为10000。
```
说明:
采样周期内被删除任务的CPUP只计算,不显示,所以获取所有线程的CPUP有可能小于总值(单核为10000,多核10000*CPU核数)。
```
### 为什么需要线程CPU占用率
线程CPU占用率表示系统中所有线程对CPU的占用情况,用户可以通过查看各个线程CPU占用率来判断所有线程的负载,以便及时获取该线程的负载是否符合设计预期。
## 运作机制
### 系统CPU占用率运作机制
UniProton的系统级CPU占用率依赖于Tick模块,通过Tick采样IDLE任务或IDLE软中断计数来实现。
#### 获取系统CPU占用率原理
- 任务框架:系统通过对采样周期内IDLE任务的循环次数与空跑IDLE任务的循环次数比较,计算出此时的系统CPU占用率。
#### CPU占用率告警
在每个采样点,获取当前CPU占用率,如果CPU占用率超过用户配置的CPU占用率告警阈值,通过用户注册的回调函数把告警信息通知用户。
持续的CPU占用率超过告警阈值,只有第一次进行告警,在本次告警恢复后,才能进行下一次告警。
当CPU占用率从告警状态返回到低于CPU占用率告警恢复阈值时,通过回调函数,报告恢复信息。
在统计当前CPU占用率时,如果此时系统运行时间没有达到第一个采样周期,即系统还未统计CPU占用率,则返回的占用率统计结果为初始值(0xffffffff)。
```
说明:
任务框架:idle线程是任务,即任务没有被裁剪的情况。
```
### 线程CPU占用率运作机制
UniProton的线程级CPU占用率支持两种方式确定采样周期。第一种,配置项中的采样周期配置不为0,则线程级CPUP采样周期为配置项中的采样周期值,这种方式,需要依赖于Tick模块;第二种,配置项中的采样周期配置为0,则采样周期为两次调用SRE_CpupNow或者SRE_CpupThread接口之间的间隔。
#### 获取线程CPU占用率原理
任务框架:系统通过计算在一定时间内,单个线程占用的CPU时间,计算出其CPU占用率。
```
说明:
任务框架:idle线程是任务,即任务没有被裁剪的情况。
```
+9
View File
@@ -0,0 +1,9 @@
## 错误处理
错误处理模块实现OS内部错误码记录功能。OS内部错误码无法通过接口返回,通常会上报错误处理模块进行记录。用户可以通过挂接错误处理的钩子函数,进行特定的处理。如果OS上报的错误是致命错误,系统会进行异常流程接管,保存现场以便定位问题。
用户可以调用错误处理接口,但不会进行错误码记录,只会执行用户注册钩子函数。
用户可以调用获取线程上报的最后一个错误码接口,获取本线程系统上报的最后一个错误码。
对于任务线程,可以在每个任务中调用获取线程上报的最后一个错误码接口,获取当前任务或软中断系统最后上报的错误码。对于除任务外的所有其他线程,可以调用该接口,获取所有其他线程系统上报的最后一个错误码。
+45
View File
@@ -0,0 +1,45 @@
## 事件介绍
### 什么是事件
事件机制可以实现线程之间的通讯。事件通讯只能是事件类型的通讯,无数据传输。 UniProton事件作为任务的扩展,实现任务之间的通讯。每个任务支持32种类型事件(32个 bit位,每bit代表一种事件类型)。 UniProton提供读取本任务事件和写指定任务事件功能。读事件时可以同时读取多种事件,也可以只读一种事件,写事件时也可以同时写一种或多种类型事件。
### 为什么需要事件
用户在创建多个任务时,往往需要一些任务之间的同步,即一个任务运行到某些特定的代码时需要通知另外一个任务去做对应的处理。引入事件机制,可以给需要通知的任务发送事件(写事件),也可以在任务中接收事件(读事件),事件接收成功后根据事件类型做对应的处理。
### 运作机制
#### 写事件运作机制
<!--
![写事件运作机制](../images/write_event.png)
**说明:**
-->
在写事件过程中,需要完成以下步骤:
1. 对指定任务事件类型写上输入事件。
2. 判断目的任务是否正在接收等待事件,且其等待的事件是否已经符合唤醒条件。(唤醒条件即读取的事件已经发生)
3. 如果符合唤醒条件,则需清除任务读事件状态。
4. 清除任务超时状态。
5. 在任务没有被挂起的情况下,需要将任务加入就绪队列并尝试任务调度。
#### 读事件运作机制
<!--
![读事件运作机制](../images/read_event.png)
**说明:**
-->
读事件过程如下:
1. 根据入参事件掩码类型对自身任务输入读取事件类型。
2. 判断事件读取模式,是读取输入的所有事件还是其中的任意一种事件。
3. 根据读取模式,判断期望的事件是否满足读取情况。
4. 判断事件等待模式:如果为等待事件模式则根据模式来设置相应的超时时间;如果为非等待模式则事件读取失败。
5. 如果需要等待阻塞读取,则需要将自己任务从就绪列表中删除,并进行任务调度。
6. 读取成功后,清除读到的事件类型,并且把事件类型返回。
### 注意事项
- 事件无需创建,每个任务创建后自动支持32种事件类型。
- 在非任务线程中可以对任务写事件,但不能读事件。
- 不能在IDLE任务中读事件,因为读事件可能会引发IDLE任务阻塞(当期望的事件未发生时),从而导致异常发生。
- 在系统初始化之前不能调用读写事件接口。如果调用,则系统运行会不正常。
+7
View File
@@ -0,0 +1,7 @@
## 异常接管介绍
异常接管属于维测特性,其主要目的是在系统出现异常后,记录尽可能多的异常现场信息,方便后续问题定位。同时提供异常时的钩子函数,以便用户能够在异常发生时做一些用户化的特殊处理。
### 异常接管
异常接管是UniProton调试部件的一个子模块。其主要功能是接管内部异常的处理或者一些外部硬件异常。UniProton接管异常是为了记录尽可能多的异常现场信息,方便后续问题定位。同时提供相应的钩子函数以便产品能够对异常进行必要的附加处理。
+19
View File
@@ -0,0 +1,19 @@
## 硬中断介绍
### 什么是硬中断
硬中断是由外设发给CPU的信号,使得CPU暂停当前的任务,转而去响应外设请求的过程。
### 为什么需要硬中断
CPU的处理速度比外设的运行速度快很多,外设需要CPU响应请求前,CPU可以执行其它任务。外设需要CPU立即响应请求时,就中断CPU的当前任务来响应请求。请求响应结束后,CPU再恢复被打断的任务继续执行。所以使用硬中断将大大提高系统对外设请求响应的实时性以及执行效率。
## 注意事项
### 硬中断模块内部使用注意事项
- 使用硬中断时,需先设置中断模式属性再创建中断处理函数,再使能该中断。
- 未创建的硬中断被响应,则上报致命错误,进入异常接管流程。
- 使用硬中断时,必须先确认对应中断号是否是系统独占的中断号,以免破坏系统运行状态。
- 当外设使用电平中断进行中断触发时,中断处理过程中电平一直存在,需要在中断服务程序中由用户去清除。
- 组合型硬中断处理函数的执行顺序和创建顺序是一致的。
- 使能、禁止指定硬中断的返回值只表示该硬中断使能、禁止前的状态值,而不包括其他硬中断的状态值。
- 组合型中断处理函数中再次注册该中断的处理函数,则新注册的处理函数会被执行。
### 硬中断与其它模块交互的注意事项
- 关中断(PRT_HwiLock)只是屏蔽中断,不会禁止任务之间的切换。
File diff suppressed because it is too large Load Diff
+23
View File
@@ -0,0 +1,23 @@
## 内存管理介绍
内存管理主要工作是动态的划分并管理用户分配好的内存区间。当程序某一部分需要使用内存,可以通过操作系统的内存申请函数索取指定大小内存块,一旦使用完毕,通过内存释放函数归还所占用内存,使之可以重复使用。在系统运行过程中,内存管理模块通过对内存的申请/释放操作管理用户和OS对内存的使用,使内存的利用率和使用效率达到最优。
### 内存基本概念
#### 内存块 slice
用户申请到的一片连续内存空间,是内存管理的最小单元。
#### 算法 arithmetic
内存管理的一种策略,如FSC。
### 内存算法
目前提供了私有FSC算法
## 开发流程
#### 步骤一:设置内存管理模块配置项
使用UniProton内存管理模块,需要进行配置项的设置,需要配置的项包括缺省分区首地址、分区大小等。
#### 步骤二:使用内存管理模块
当需要使用内存时,需要先创建一个指定内存管理算法的内存分区,通过调用内存申请接口申请合适大小的内存,就可以对申请到的内存进行操作(包括写操作,然后给其他模块传递消息等);如果是动态内存,当内存使用完,需要对这块内存进行释放,防止发生内存泄漏。
+23
View File
@@ -0,0 +1,23 @@
## 队列介绍
### 什么是队列
队列(Queue),又称消息队列。是线程间实现通信的一种方式。实现了数据的存储和传递功能。根据优先级可以将数据写入到队列头或队列尾,但只能从队列的头处读取数据。
### 为什么需要队列
用户在业务处理时,需要有大量数据的存储和传递功能,用户可以采用数组方式实现,但管理比较麻烦。UniProton的队列机制提供了通用的同步和异步通信机制,可以使各个相关任务/中断之间通过队列来发送和接收数据(消息)。队列发送和接收消息可以根据用户不同需求,传递不同长度的数据。
## 概念解释
| 名称 | 解释说明 |
| ---- | ---- |
| 队列ID | 用于唯一标识一个队列,在创建队列时通过参数返回给用户,以便进行读写操作。 |
| 队列消息单元 | 队列中数据读取的基本单元。每一次写队列,都会使用一个新的消息单元;每一次读队列,都会从最早写入的消息单元中读取数据。 |
| 队列消息单元大小 | 指队列中成员的大小(成员大小均相等),单位:字节。 |
| 队列长度 | 队列最大消息个数,即该队列最多支持的成员个数。单位:个。 |
| 紧急写入 | 消息写入到队列头,优先读取。 |
| 普通写入 | 消息写入到队列尾,按先进先出方式读取。 |
### 运作机制
创建队列时,根据用户传入队列长度和消息单元大小来开辟相应的内存空间以供该队列使用。在队列控制块中维护一个头指针Head和一个尾指针Tail来表示当前队列中数据存储情况。头指针Head表示队列中被占用消息的起始地址,尾指针Tail表示队列中空闲消息的起始地址。
- 刚创建时Head和Tail指针均指向队列起始地址。
- 在写队列时,先PEND一下写的信号量;再根据Tail指针找到被占用消息单元末尾的空闲消息单元(紧急消息是头部的空闲消息单元)作为数据写入对象;如果Tail指针已经指向队列尾则采用回卷方式重新指向队列头;最后POST读的信号量。
- 在读队列时,先PEND一下读的信号量;根据Head指针找到最先写入队列中的消息单元进行读取;如果Head指针已经指向队列尾则采用回卷方式重新指向队列头;最后POST写的信号量。
+32
View File
@@ -0,0 +1,32 @@
## 信号量介绍
信号量(Semaphore)常用于协助一组互相竞争的任务来访问临界资源,在需要互斥的场合作为临界资源计数使用。
信号量对象具有一个内部计数器。它支持两种操作:申请(Pend)和释放(Post)。
- 任务执行Pend操作会等待指定的信号量,若其计数器值大于0,则计数器值直接减1,返回成功。否则任务阻塞,等待其他线程释放该信号量,等待的容忍时间可设定。
- 任务执行Post操作会释放指定的信号量,若没有其它任务等待该信号量,则直接将计数器加1,返回成功。否则如有任务阻塞,根据不同情况唤醒:
1. FIFO唤醒方式:SEM_MODE_FIFO,默认信号量唤醒方式,这种唤醒方式会唤醒最早阻塞于该信号量上的任务。
2. 优先级唤醒方式:SEM_MODE_PRIOR,核内信号量支持的唤醒方式,创建时指定,这种唤醒方式会唤醒阻塞于该信号量上的最高优先级的任务。
通常一个信号量的计数器值对应有效的资源数,表示剩下的可被占用的互斥资源数。其值的含义分两种情况:
- 为0,表示没有积累下来的Post操作,且有可能有在此信号量上阻塞的任务。
- 为正值,表示当前有一个或多个可供Pend的信号量计数。
## 运作机制
信号量是结合任务使用的,可以用作任务访问的临界资源的标识,通过信号量的Pend/Post 操作完成临界资源之间的互斥。
### Pend操作原理
1. Pend操作后系统会判断信号量计数是否大于0,大于0则减1后返回操作成功,否则该任务进入阻塞态。进入阻塞态后系统将继续执行就绪任务队列中优先级最高的任务。
2. 任务进入阻塞态后,会等待信号量的释放,如果等待超时,则返回Pend操作失败。如果等待到信号量释放则返回操作成功。
### Post操作原理
1. Post操作判断是否有任务阻塞于指定信号量,若没有,则对信号量计数加1直接返回,否则根据唤醒方式唤醒阻塞在该信号量的相应阻塞任务。若为FIFO方式,则唤醒最先阻塞的任务;若为优先级方式,则唤醒阻塞在此信号量的最高优先级任务。
### 注意事项
- 目前,系统中运行的线程有硬中断和任务。对于信号量的P/V操作,在带有容忍时间的P操作过程中,如果P不到信号量,即会使自身阻塞于该信号量。硬中断不允许出现挂起和阻塞的状态,因此硬中断线程中不允许pend信号量。
- 等待互斥信号量的任务在等待超时后可能不会立刻得到运行。
- 不能在IDLE任务中等待信号量。
### 具体使用流程
使用UniProton提供的信号量功能,要先创建信号量,然后申请信号量,临界资源使用完后,释放信号量,最后删除该信号量。
+44
View File
@@ -0,0 +1,44 @@
## 任务介绍
### 什么是任务
任务是代码运行的一个映象。从系统的角度看,任务是竞争系统资源的最小运行单元。任务可以使用或等待CPU、内存空间等系统资源,并独立于其它任务一起并发运行。
UniProton是一个单进程支持多线程的操作系统。在UniProton中,一个任务表示一个线程。
### 为什么需要任务
用户在编写大型程序时,往往会包含多个模块或多个功能,这些代码之间需要一些切换、同步等动作。如果切换、同步这些功能完全由用户自己去实现,会花费很大的精力。UniProton的任务模块可以给用户提供多个任务,实现了任务之间的切换和通讯,帮助用户管理业务程序流程。这样用户可以将更多的精力投入到业务功能的实现中。
## 概念解释
| 名称 | 解释说明 |
| ---- | ---- |
| 任务优先级 | 任务优先级表示任务执行的优先顺序,用数字表示。数字越小,优先级越高。就绪列表中高优先级的任务先得到执行,同优先级任务按照就绪列表顺序执行,新创建的任务位于就绪列表尾部。多个任务可以具有相同的优先级。 |
| 任务原始优先级 | UniProton在处理任务优先级反转时,任务优先级为当前运行优先级,而创建时的优先级和动态调整的优先级由任务原始优先级表示。处理完毕优先级反转后,任务当前优先级会回到该原始优先级。 |
| 任务状态 | UniProton 系统中的每个任务都有多种运行状态,包括就绪、运行、阻塞、挂起。 |
| 任务PID | 任务ID作为任务的重要标识,在任务创建时通过参数返回给用户。用户可以通过任务ID对指定任务进行任务挂起、任务恢复、查询任务信息等操作。 |
| 任务入口函数 | 任务创建发生调度后将首次执行的函数。该函数由用户实现,在任务创建时通过任务创建结构体指定。 |
| 任务上下文 | 任务在运行过程中使用到的一些资源如寄存器、栈指针等,我们称为任务上下文。 |
| 任务栈 | 系统给每一个分配的一块内存空间,任务切换时会将本任务的上下文保存在任务栈中,以便任务恢复时从任务栈中提取任务上下文从而继续执行。 |
| 任务栈区间 | 系统中的一块内存空间,专门用来保存任务的任务栈。 |
| 任务自删除 | 当一个任务(任务A)的所有操作都已结束,下一个任务创建时系统会删除任务A占用的相关资源。详细请参见SRE_TaskDelete 的注意事项。 |
| IDLE任务 | 若系统未裁剪任务模块,则系统在初始化时默认会创建一个最低优先级的IDLE任务,作为背景任务,以确保系统在没有其它运行态的任务时正常运行。 |
## 运作机制
UniProton中的任务是抢占式调度机制,而非时间片轮转调度方式。高优先级的任务可打断低优先级任务的执行。低优先级任务必须在高优先级任务挂起或阻塞后才能得到调度。
### AMP调度方式
任务调度会使系统切换到当前就绪列表中最高优先级的任务。任务调度是否一定会发生任务切换,还需要看系统整体运行状态。任务调度流程如下:
1. 获取就绪列表中最高优先级任务。
2. 判断最高优先级任务是否为当前任务、判断是否锁任务调度。
3. 判断是否在中断中,如果在中断中,则不需要保存当前任务上下文。
4. 保存当前任务上下文。
5. 将当前任务切换到最高优先级任务。并恢复最高优先级任务上下文。
```
说明:
· 触发任务调度动作包括:创建任务(OS初始化中创建任务不会发生任务调度)、任务挂起、任务恢复、任务延时、解锁任务调度、信号量操作等。
· 阻塞的任务不在就绪列表中。
· 当前任务为最高优先级任务或锁任务调度时,任务调度会退出,不会进行任务切换。
· 如果在中断中发生任务调度,那么将记录下切换标志位,在用户ISR退出后进行任务切换。由于中断响应是已经将保存过当前任务上下文,所以中断退出后切换任务只需要恢复最高优先级任务上下文即可。
```
+26
View File
@@ -0,0 +1,26 @@
## 软件定时器介绍
### 什么是软件定时器
软件定时器是基于系统Tick中断而由软件来模拟的的定时器,其时间精准度为ms级别。
### 为什么需要软件定时器
各个产品上都有很多定时业务,但往往硬件定时器的资源是有限的,不能满足业务要求。为了满足用户需求,提供更多的定时器,UniProton操作系统提供了软件定时器功能。软件定时器扩展了定时器的数量,允许创建更多的定时业务。
## 概念解释
| 名称 | 解释说明 |
| ---- | ---- |
| 单次触发模式 | 只触发一次,之后不会再次触发 |
| 周期触发模式 | 循环触发,每隔固定的时间间隔触发一次 |
| 定时器周期 | 定时器的定时时间间隔,软件定时器单位是ms |
| 超时处理函数 | 定时器回调函数 |
## 运作机制
软件定时器以Tick中断作为基本的计时单位,即软件定时器的时间间隔必须是Tick中断时间间隔的整数倍。例如,Tick中断的时间间隔是0.2ms,则软件定时器的时间间隔只能是interval * 0.2ms。
由于软件定时器以Tick中断作为计数时钟,所以在Tick中断的处理中对软件定时器是否超时进行扫描。当扫描到超时的定时器后,调用该定时器的超时处理函数。
流程:
1. 软件定时器初始化。对定时器所需内存分配、控制块数据和定时器链表结构进行初始化,并建立软件定时器的内部逻辑结构,为软件定时器的操作做好准备。
2. 创建软件定时器。先根据定时器管理器中的空闲定时器数是否大于>0,>0表示有空闲定时器,创建的时候先过滤不合法的参数,如果输入的参数合法,则从定时器空闲链表中取出一个定时器,对这个定时器设定超时时间、触发类型、超时处理函数和超时任务参数,并把定时器的状态设置为创建未启动状态,然后把定时器ID号写入返回参数。由返回参数把定时器ID号返回给创建者。这里要注意,设定的软件定时器的毫秒数转换成Tick数必须为整数。相应的ms转换成tick的公式为:每秒的Tick数*定时ms数/1000。
3. 启动软件定时器。启动定时器后,设置定时器状态为计时状态。
4. 超时扫描。对计时链表进行超时扫描,如果有定时器超时,则把所有超时定时器从计时链表中摘下来,对所有超时的定时器进行超时服务处理。
5. 处理超时服务。处理完超时服务后,如果定时器的触发模式是单次触发,则将该定时器设置为创建状态,否则把定时器挂到计时链表中,重新计数。
+77
View File
@@ -0,0 +1,77 @@
## 快速入门:开发Hello World
快速入门通过完成经典的“Hello World”把搭建UniProton开发环境的各步骤进行实例说明,让用户更直观地初步了解如何基于UniProton进行开发。
## 开发环境说明
开发平台:cortex_m4
OS版本信息:Linux
集成开发环境:UniProton-docker
### 实现过程
<ol>
<li>进入到用户的工作目录,这里假设为/workspace/UniProton。</li>
<li>将UniProton的源码放在/workspace/UniProton目录下。</li>
<li>在docker环境中搭建工程。</li>
<li>配置链接器配置文件(.lds文件)。</li>
<li>配置功能模块,用户需要按照自己实际使用模块配置功能模块。</li>
<li>在该工程下规划各开发模块的目录结构,如在/UniProton/src/config/prt_config.c文件中实现用户程序。</li>
<li>在docker中编译整个工程,编译完成后在/UniProton/output目录下生成可执行文件hello。</li>
<li>加载到单板上运行可执行文件hello。</li>
</ol>
### Hello World 示例程序
在main.c文件中编写Hello World示例程序,如参考内容如下(如前所述,PRT_HardBootInit/PRT_HardDrvInit接口中添加用户自定义硬件模块初始化程序,PRT_AppInit接口中添加用户业务代码):
```c
#include "prt_task.h"
#include "prt_config.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cpluscplus */
#endif /* __cpluscplus */
U32 PRT_HardDrvInit(void)
{
return OS_OK;
}
void PRT_HardBootInit()
{
}
void OsTskUser(void)
{
printf("\n\r Hello World !\n\r");
}
U32 PRT_AppInit(void)
{
U32 ret;
TskHandle taskId;
struct TskInitParam taskParam;
taskParam.taskEntry = (TskEntryFunc)OsTskUser;
taskParam.stackSize = 0x800;
taskParam.name = "uniUserTask";
taskParam.taskPrio = OS_TSK_PRIORITY_05;
taskParam.stackAddr = 0;
ret = PRT_TaskCreate(&taskId, &taskParam);
if (ret != OS_OK) {
return ret;
}
return OS_OK;
}
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cpluscplus */
#endif /* __cpluscplus */
```
### 结果验证
在docker中编译整个工程后生成的可执行文件hello下载到单板上运行,输出结果如下:
```
Hello world!
```
+16
View File
@@ -0,0 +1,16 @@
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> -r <TARGET> <OBJECTS>")
if (${COMPILE_OPTION} STREQUAL "coverity" OR ${COMPILE_OPTION} STREQUAL "fortify" OR ${COMPILE_OPTION} STREQUAL "single")
message("Don't Compile Sec Lib In ${COMPILE_OPTION}")
else()
include_directories(libboundscheck/include)
include_directories(libboundscheck/src)
set(LIB_SEC_NAME "CortexMXsec_c")
file(GLOB_RECURSE SEC_SRC RELATIVE ${CMAKE_CURRENT_LIST_DIR} "./libboundscheck/src/*.c") #遍历搜索src目录下的所有c文件,RELATIVE为使用相对路径
add_library(${LIB_SEC_NAME} STATIC ${SEC_SRC}) #在文件夹上层选择性编译与否
set_target_properties(${LIB_SEC_NAME} PROPERTIES SUFFIX ".lib")
endif()
+10
View File
@@ -0,0 +1,10 @@
# libboundscheck使用说明
## 下载源码
链接地址: https://gitee.com/openeuler/libboundscheck
## 使用方式
将下载后的代码解压,将src和include目录粘贴到UniProton/platform/libboundscheck目录下即可。
## 编译
编译前确保将libboundscheck源码放至UniProton/platform/libboundscheck目录下,UniProton提供的cmake编译框架会自动加入安全C库的编译。
View File
View File
+17
View File
@@ -0,0 +1,17 @@
##############################下一级的编译目录 ###########################
add_subdirectory(arch)
add_subdirectory(core)
add_subdirectory(mem)
add_subdirectory(om)
add_subdirectory(security)
add_subdirectory(utility)
if(${CONFIG_OS_SUPPORT_FS})
add_subdirectory(fs)
endif()
if(${CONFIG_OS_SUPPORT_NET})
add_subdirectory(net)
endif()
+11
View File
@@ -0,0 +1,11 @@
mainmenu "UniProton Configuration"
#should source arch Kconfig first
source "arch/Kconfig"
source "core/Kconfig"
source "mem/Kconfig"
source "om/Kconfig"
source "security/Kconfig"
source "fs/Kconfig"
source "net/Kconfig"
source "utility/Kconfig"
+1
View File
@@ -0,0 +1 @@
add_subdirectory(cpu)
+31
View File
@@ -0,0 +1,31 @@
menu "Arch Modules Configuration"
source "arch/cpu/Kconfig"
menu "Generic Configuration"
config OS_HARDWARE_PLATFORM
string
default "OS_CORTEX_M4" if INTERNAL_OS_PLATFORM_M4
config OS_CPU_TYPE
string
default "OS_STM32F407" if INTERNAL_OS_CORTEX_M4
config OS_MAX_CORE_NUM
int "The maxinum number of cores"
default 1 if INTERNAL_OS_PLATFORM_M4
config INTERNAL_OS_BYTE_ORDER_LE
bool
default y
help
This indicates little endian if y
config OS_BYTE_ORDER
string
default "OS_LITTLE_ENDIAN" if INTERNAL_OS_BYTE_ORDER_LE
default "OS_BIG_ENDIAN" if !INTERNAL_OS_BYTE_ORDER_LE
endmenu
endmenu
+3
View File
@@ -0,0 +1,3 @@
if(${CONFIG_OS_ARCH_ARMV7_M})
add_subdirectory(armv7-m)
endif()
+8
View File
@@ -0,0 +1,8 @@
choice
prompt "Platform Setup"
config OS_ARCH_ARMV7_M
bool "ARMV7_M"
endchoice
source "arch/cpu/armv7-m/Kconfig"
+5
View File
@@ -0,0 +1,5 @@
if(${CONFIG_INTERNAL_OS_PLATFORM_M4})
add_subdirectory(cortex-m4)
endif()
add_subdirectory(common)
+20
View File
@@ -0,0 +1,20 @@
menu "ARM7-M Sepecfic Configuration"
depends on OS_ARCH_ARMV7_M
config INTERNAL_OS_CORTEX_M4
bool
select INTERNAL_OS_BYTE_ORDER_LE
choice
prompt "Cpu Type"
config INTERNAL_OS_PLATFORM_M4
bool "CORTEX_M4"
select INTERNAL_OS_CORTEX_M4
endchoice
source arch/cpu/armv7-m/cortex-m4/Kconfig
endmenu
@@ -0,0 +1,5 @@
add_subdirectory(boot)
add_subdirectory(exc)
add_subdirectory(hwi)
add_subdirectory(tick)
add_library(prt_port OBJECT prt_port.c)
@@ -0,0 +1 @@
add_library(prt_hw_boot OBJECT prt_hw_boot.c)
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: Hardware interrupt implementation
*/
#include "prt_attr_external.h"
OS_SEC_L4_TEXT void OsHwInit(void)
{
}
@@ -0,0 +1 @@
add_library(prt_exc OBJECT prt_exc.c)
+180
View File
@@ -0,0 +1,180 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: 异常模块的C文件。
*/
#include "prt_clk.h"
#include "prt_exc_internal.h"
#include "prt_sys_external.h"
#include "prt_task_external.h"
#include "prt_irq_external.h"
#include "prt_asm_cpu_external.h"
OS_SEC_BSS bool g_excSaveFlag;
OS_SEC_BSS struct ExcRegInfo g_excInfo;
// 异常时获取当前任务的信息
OS_SEC_BSS ExcTaskInfoFunc g_excTaskInfoGet;
OS_SEC_L4_TEXT U32 OsExcConfigInit(void)
{
return OS_OK;
}
/*
* 描述:获取异常线程信息
*/
static OS_SEC_L4_TEXT void OsExcGetThreadInfo(struct ExcInfo *excInfo)
{
struct TskInfo taskInfo;
U32 threadId = INVALIDPID;
if (memset_s(&taskInfo, sizeof(struct TskInfo), 0, sizeof(struct TskInfo)) != EOK) {
OS_GOTO_SYS_ERROR1();
}
#if defined(OS_OPTION_TASK_INFO)
/* 任务存在时 */
if ((OsTskMaxNumGet() > 0) && ((UNI_FLAG & OS_FLG_BGD_ACTIVE) != 0)) {
/* 记录当前任务ID号 */
if (PRT_TaskSelf(&threadId) == OS_OK) {
/* 获取当前任务信息 */
OS_ERR_RECORD(PRT_TaskGetInfo(threadId, &taskInfo));
}
}
#endif
/* 记录发生异常时的线程ID,发生在任务中,此项具有意义,其他线程中,此项无意义 */
excInfo->threadId = INVALIDPID;
/* 设置异常前的线程类型 */
if (g_intCount > CUR_NEST_COUNT) {
excInfo->threadType = EXC_IN_HWI;
} else if ((UNI_FLAG & OS_FLG_TICK_ACTIVE) != 0) {
excInfo->threadType = EXC_IN_TICK;
} else if ((UNI_FLAG & OS_FLG_SYS_ACTIVE) != 0) {
excInfo->threadType = EXC_IN_SYS;
} else if ((UNI_FLAG & OS_FLG_BGD_ACTIVE) != 0) {
excInfo->threadType = EXC_IN_TASK;
if (OsTskMaxNumGet() > 0) { /* 任务存在时 */
excInfo->threadId = threadId;
}
} else { // OS_FLG_BGD_ACTIVE没有置位,代表此时还在系统进程中,没有进入业务线程。
excInfo->threadType = EXC_IN_SYS_BOOT;
}
/* MSP主堆栈 */
if ((excInfo->sp >= OsGetSysStackTop()) && (excInfo->sp <= OsGetSysStackBottom())) {
excInfo->stackBottom = OsGetSysStackBottom();
} else { /* PSP进程堆栈 */
excInfo->stackBottom = TRUNCATE((taskInfo.topOfStack + taskInfo.stackSize), OS_TSK_STACK_ADDR_ALIGN);
}
}
/*
* 描述:记录异常信息
*/
OS_SEC_L4_TEXT void OsExcSaveInfo(struct ExcRegInfo *regs)
{
struct ExcInfo *excInfo = OS_EXC_INFO_ADDR;
char *version = NULL;
U64 count;
/* 记录os版本号 */
version = PRT_SysGetOsVersion();
if (version != NULL) {
if (strncpy_s(excInfo->osVer, sizeof(excInfo->osVer),
version, sizeof(excInfo->osVer) - 1) != EOK) {
OS_GOTO_SYS_ERROR1();
}
}
excInfo->osVer[OS_SYS_OS_VER_LEN - 1] = '\0';
/* 记录异常类型 */
excInfo->excCause = regs->excType;
/* 记录CPU ID */
excInfo->coreId = OsGetHwThreadId();
/* 设置字节序 */
excInfo->byteOrder = OS_BYTE_ORDER;
/* 记录CPU类型 */
excInfo->cpuType = OsGetCpuType();
/* 记录CPU TICK值 */
count = PRT_ClkGetCycleCount64();
excInfo->cpuTick = count;
/* 记录当前异常嵌套次数 */
excInfo->nestCnt = CUR_NEST_COUNT;
/* 记录寄存器信息 */
excInfo->regInfo = (*regs);
/* 记录异常前栈指针 */
excInfo->sp = (regs->context)->sp;
/* 记录异常前栈底 */
excInfo->stackBottom = INVALIDSTACKBOTTOM;
OsExcGetThreadInfo(excInfo);
}
static OS_SEC_L4_TEXT void OsExcRecordInfo(U32 excType, U32 faultAddr, struct ExcContext *excBufAddr)
{
// 若为1时faultAddr有效
U16 tmpFlag = (U16)OS_GET_32BIT_HIGH_16BIT(excType);
g_excInfo.excType = excType;
/* 此掩码在CDA解析时需要判断 */
if (((U32)tmpFlag & OS_EXC_FLAG_FAULTADDR_VALID) != 0) {
g_excInfo.faultAddr = faultAddr;
} else {
g_excInfo.faultAddr = OS_EXC_IMPRECISE_ACCESS_ADDR;
}
/* 异常上下文记录 */
g_excInfo.context = excBufAddr;
}
static OS_SEC_L4_TEXT void OsReboot(void)
{
while (1) {
/* Wait for HWWDG to reboot board. */
}
}
/*
* 描述:EXC模块的处理分发函数
*/
OS_SEC_L4_TEXT void OsExcHandleEntryM4(U32 excType, U32 faultAddr, struct ExcContext *excBufAddr)
{
CUR_NEST_COUNT++;
g_intCount++;
UNI_FLAG |= OS_FLG_HWI_ACTIVE;
OsExcRecordInfo(excType, faultAddr, excBufAddr);
if (OS_EXC_MAX_NEST_DEPTH < CUR_NEST_COUNT || g_excSaveFlag == TRUE) {
OsReboot();
}
if (memset_s(OS_EXC_INFO_ADDR, EXC_RECORD_SIZE, 0, EXC_RECORD_SIZE) != EOK) {
OS_GOTO_SYS_ERROR1();
}
/* 没有初始化完成分配异常信息记录空间 */
OsExcSaveInfo(&g_excInfo);
g_excSaveFlag = TRUE;
if (g_excModInfo.excepHook != NULL) {
(void)g_excModInfo.excepHook(OS_EXC_INFO_ADDR);
}
OsReboot();
}
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: hw模块内部头文件。
*/
#ifndef PRT_EXC_INTERNAL_H
#define PRT_EXC_INTERNAL_H
#include "prt_exc_external.h"
/*
* 模块内宏定义
*/
#define OS_EXC_MAX_NEST_DEPTH 5
#define OS_EXC_FLAG_FAULTADDR_VALID 0x01U /* 异常类型:faultAddr域是否有效 标志位 */
#define OS_EXC_IMPRECISE_ACCESS_ADDR 0xABABABABUL
#define INVALIDPID 0xFFFFFFFFUL
#define INVALIDSTACKBOTTOM 0xFFFFFFFFUL
extern void OsExcSaveInfo(struct ExcRegInfo *regs);
extern void OsExcHandleEntryM4(U32 excType, U32 faultAddr, struct ExcContext *excBufAddr);
#endif /* PRT_EXC_INTERNAL_H */
@@ -0,0 +1,2 @@
add_library(prt_hwi OBJECT prt_hwi.c)
add_library(prt_vi_dispatch OBJECT prt_vi_dispatch.c)
+244
View File
@@ -0,0 +1,244 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: Hardware interrupt implementation
*/
#include "prt_hook_external.h"
#include "prt_lib_external.h"
#include "prt_task_external.h"
#include "prt_hwi_internal.h"
#if defined(OS_OPTION_HWI_MAX_NUM_CONFIG)
OS_SEC_BSS U32 g_hwiMaxNumConfig;
#endif
OS_SEC_BSS OsVoidFunc g_excTrap;
/*
* 重定位以后的向量表,
* 其最后一个四字节表示当前运行的中断号,初始化系统定义异常向量,以便初始化阶段异常接管
*/
VEC_SEC_DATA HwiPubintFunc g_hwiTable[OS_MX_VECTOR_CNT + 1] = {
(HwiPubintFunc)MSTACK_VECTOR,
(HwiPubintFunc)OsResetVector,
};
OS_SEC_L4_TEXT void OsScheduleInit(void)
{
OS_SET_VECTOR(OS_EXC_PEND_SV, OsPendSv);
OS_SET_VECTOR(OS_EXC_SVC_CALL, OsSvchandler);
NVIC_SET_EXC_PRI(OS_EXC_PEND_SV, OS_HWI_PRI_LOWEST);
NVIC_SET_EXC_PRI(OS_EXC_SVC_CALL, OS_HWI_PRI_HIGHEST);
}
OS_SEC_L4_TEXT void OsHwiGICInit(void)
{
U32 loop;
/* 系统中断向量表初始化 */
for (loop = 0; loop < OS_MX_SYS_VECTOR_CNT; loop++) {
g_hwiTable[loop] = (HwiPubintFunc)OsHwiDefaultHandler;
}
OS_SET_VECTOR(0, (HwiPubintFunc)MSTACK_VECTOR);
OS_SET_VECTOR(OS_EXC_RESET, OsResetVector);
OS_SET_VECTOR(OS_EXC_NMI, OsExcNmi);
OS_SET_VECTOR(OS_EXC_HARD_FAULT, OsExcHardFault);
OS_SET_VECTOR(OS_EXC_MPU_FAULT, OsExcMemFault);
OS_SET_VECTOR(OS_EXC_BUS_FAULT, OsExcBusFault);
OS_SET_VECTOR(OS_EXC_USAGE_FAULT, OsExcUsageFault);
g_excTrap = (OsVoidFunc)OsExcSvcCall;
OsScheduleInit();
OS_SET_VECTOR(OS_EXC_SYS_TICK, OsTickIsr);
// 将Tick的优先级置为最低
NVIC_SET_EXC_PRI(OS_EXC_SYS_TICK, OS_HWI_PRI_LOWEST);
/* 用户中断向量表初始化 */
for (loop = OS_MX_SYS_VECTOR_CNT; loop < OS_MX_VECTOR_CNT; loop++) {
g_hwiTable[loop] = OsInterrupt;
}
/* 中断向量表定位 */
*(volatile U32 *)OS_NVIC_VTOR = (U32)(uintptr_t)g_hwiTable;
/*
* 访问钥匙:任何对该寄存器的写操作都必须同时把0x05FA写入此段,否则写操作被忽略
* 位段10:8为优先级分组
*/
*(volatile U32 *)OS_NVIC_AIRCR = (OS_NVIC_AIRCR_REG_ACCESS_PSW |
(OS_NVIC_AIRCR_PRIGROUP << OS_NVIC_AIRCR_PRIGOUP_BIT_OFFSET));
}
/*
* 描述:默认外部中断处理函数
*/
OS_SEC_TEXT void OsInterrupt(void)
{
HwiHandle hwiNum;
uintptr_t intSave;
/* 操作basepri 设置成关中断 */
intSave = PRT_HwiLock();
UNI_FLAG |= OS_FLG_HWI_ACTIVE;
g_intCount++;
/* 取外部中断号,中断号减去系统中断号 */
hwiNum = OsIntNumGet() - OS_MX_SYS_VECTOR_CNT;
#ifdef OS_OPTION_HWI_MAX_NUM_CONFIG
if (hwiNum > g_hwiMaxNumConfig) {
PRT_HwiRestore(intSave);
return;
}
#endif
OsTskHighestSet();
(void)PRT_HwiUnLock();
// ISR执行(这里一处开中断)
OsHwiHookDispatcher(hwiNum);
(void)PRT_HwiLock();
g_intCount--;
if (g_intCount == 0) {
UNI_FLAG &= ~OS_FLG_HWI_ACTIVE;
}
/* 恢复 basepri */
PRT_HwiRestore(intSave);
if ((UNI_FLAG & OS_FLG_TSK_REQ) != 0) {
OsHwiTrap();
}
}
/*
* 描述:硬中断模式设置
*/
OS_SEC_L4_TEXT void OsHwiPrioritySet(HwiHandle hwiNum, HwiPrior hwiPrio)
{
/* 设置优先级,当前芯片高4位有效,左移4位 */
NVIC_SET_IRQ_PRI(hwiNum, OS_HWI_GET_HWI_PRIO(hwiPrio));
}
OS_SEC_L4_TEXT U32 OsHwiPriorityGet(HwiHandle hwiNum)
{
return (U32)OS_HWI_GET_USER_PRIO((*((volatile U8 *)((uintptr_t)OS_NVIC_PRI_BASE + (hwiNum)))));
}
/*
* 描述:使能指定中断号
*/
OS_SEC_L2_TEXT U32 PRT_HwiEnable(HwiHandle hwiNum)
{
uintptr_t intSave;
if (hwiNum > OS_HWI_MAX) {
return OS_ERRNO_HWI_NUM_INVALID;
}
intSave = PRT_HwiLock();
NVIC_SET_IRQ(hwiNum);
PRT_HwiRestore(intSave);
return OS_OK;
}
/*
* 描述:清除所有的中断请求位
*/
OS_SEC_L2_TEXT void PRT_HwiClearAllPending(void)
{
uintptr_t intSave;
U32 loop;
intSave = PRT_HwiLock();
for (loop = 0; loop < OS_HWI_CLRPEND_REG_NUM; loop += sizeof(U32)) {
*(volatile U32 *)((uintptr_t)OS_NVIC_CLRPEND_BASE + loop) = OS_MAX_U32;
}
PRT_HwiRestore(intSave);
return;
}
/*
* 描述:清除单个硬中断的Pending位
*/
OS_SEC_L2_TEXT U32 PRT_HwiClearPendingBit(HwiHandle hwiNum)
{
uintptr_t intSave;
if (hwiNum > OS_HWI_MAX) {
return OS_ERRNO_HWI_NUM_INVALID;
}
intSave = PRT_HwiLock();
NVIC_CLR_IRQ_PEND(hwiNum);
PRT_HwiRestore(intSave);
return OS_OK;
}
/*
* 描述:触发指定硬中断号
*/
OS_SEC_L2_TEXT U32 PRT_HwiTrigger(U32 dstCore, HwiHandle hwiNum)
{
uintptr_t intSave;
if (hwiNum > OS_HWI_MAX) {
return OS_ERRNO_HWI_NUM_INVALID;
}
if (OsGetHwThreadId() != dstCore) {
return OS_ERRNO_HWI_CORE_ID_INVALID;
}
intSave = PRT_HwiLock();
NVIC_SET_IRQ_PEND(hwiNum);
PRT_HwiRestore(intSave);
return OS_OK;
}
/*
* 描述:禁止指定中断号
*/
OS_SEC_L2_TEXT U32 PRT_HwiDisable(HwiHandle hwiNum)
{
uintptr_t intSave;
if (hwiNum > OS_HWI_MAX) {
return OS_ERRNO_HWI_NUM_INVALID;
}
intSave = PRT_HwiLock();
NVIC_CLR_IRQ(hwiNum);
PRT_HwiRestore(intSave);
return OS_OK;
}
OS_SEC_L4_TEXT U32 PRT_HwiDelExitHook(HwiExitHook hook)
{
return OsHookDel(OS_HOOK_HWI_EXIT, (OsVoidFunc)hook);
}
OS_SEC_L4_TEXT U32 PRT_HwiAddExitHook(HwiExitHook hook)
{
return OsHookAdd(OS_HOOK_HWI_EXIT, (OsVoidFunc)hook);
}
OS_SEC_L4_TEXT U32 PRT_HwiDelEntryHook(HwiEntryHook hook)
{
return OsHookDel(OS_HOOK_HWI_ENTRY, (OsVoidFunc)hook);
}
OS_SEC_L4_TEXT U32 PRT_HwiAddEntryHook(HwiEntryHook hook)
{
return OsHookAdd(OS_HOOK_HWI_ENTRY, (OsVoidFunc)hook);
}
@@ -0,0 +1,122 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: hwi模块内部头文件。
*/
#ifndef PRT_HWI_INTERNAL_H
#define PRT_HWI_INTERNAL_H
#include "prt_hwi_external.h"
#include "prt_sys_external.h"
#include "prt_irq_external.h"
/*
* 模块内宏定义
*/
#define OS_EXC_RESET 1
#define OS_EXC_NMI 2
#define OS_EXC_HARD_FAULT 3
#define OS_EXC_MPU_FAULT 4
#define OS_EXC_BUS_FAULT 5
#define OS_EXC_USAGE_FAULT 6
#define OS_EXC_SVC_CALL 11
#define OS_EXC_PEND_SV 14
#define OS_EXC_SYS_TICK 15
#define OS_SYS_HWI_NUM 16
#define OS_HWI_NUM_SHIFT_BIT 5
#define OS_NVIC_AIRCR_REG_ACCESS_PSW 0x05FA0000U
#define OS_NVIC_AIRCR_PRIGOUP_BIT_OFFSET 8 /* [10:8]位标识优先级分组 */
#define OS_HWI_ENABLE 1 /* HW使能标识 */
#define OS_HWI_CLRPEND_REG_NUM (((OS_MX_IRQ_VECTOR_CNT + 31) / 32) << 2) /* 清除PEND位寄存器数 */
#define OS_SET_VECTOR(num, vector) (g_hwiTable[(num)] = (vector))
#define OS_GET_HWI_REG_OFFSET(hwiNum) (((hwiNum) >> OS_HWI_NUM_SHIFT_BIT) << 2)
/*
* 模块间函数声明
*/
extern void OsExcNmi(void);
extern void OsExcMemFault(void);
extern void OsExcBusFault(void);
extern void OsExcUsageFault(void);
extern void OsExcSvcCall(void);
extern void OsExcHardFault(void);
extern void OsSvchandler(void);
extern void OsResetVector(void);
extern void OsPendSv(void);
extern void OsInterrupt(void);
/* ** 向量表偏移量寄存器 VTOR */
#define OS_NVIC_VTOR 0xE000ED08UL
/* ** 中断优先级寄存器阵列 */
#define OS_NVIC_PRI_BASE 0xE000E400UL
/* ** 中断使能寄存器族 SETENA 0xE000E100-0xE000E11C */
#define OS_NVIC_SETENA_BASE 0xE000E100UL
/* ** 中断除能寄存器族 CLRENA 0xE000E180-0xE000E19C */
#define OS_NVIC_CLRENA_BASE 0xE000E180UL
/* ** 系统异常优先级寄存器阵列 */
#define OS_NVIC_EXCPRI_BASE 0xE000ED18UL
/* *** 中断控制及状态寄存器 ICSR */
#define OS_NVIC_INT_CTRL 0xE000ED04UL
/* ** 中断悬起清除寄存器(CLRPEND) 0xE000E280 - 0xE000_E29C */
#define OS_NVIC_CLRPEND_BASE 0xE000E280UL
/* ** 中断设置悬起寄存器(SETPEND) 0xE000_E200 0xE000_E21C */
#define OS_NVIC_SETPEND_BASE 0xE000E200UL
/* 应用程序中断及复位控制寄存器 AIRCR */
#define OS_NVIC_AIRCR 0xE000ED0CUL
/* 使能中断位,寄存器置1有效,置0情况下不影响 */
#define NVIC_SET_IRQ(hwiNum) \
do { \
*(volatile U32 *)((uintptr_t)OS_NVIC_SETENA_BASE + (((hwiNum) >> 5) << 2)) = 1UL << ((hwiNum) & 0x1FUL); \
} while (0)
/* 清除中断位,寄存器置1有效,置0情况下不影响 */
#define NVIC_CLR_IRQ(hwiNum) \
do { \
*(volatile U32 *)((uintptr_t)OS_NVIC_CLRENA_BASE + (((hwiNum) >> 5) << 2)) = 1UL << ((hwiNum) & 0x1FUL); \
} while (0)
/* 设置中断优先级 */
#define NVIC_SET_IRQ_PRI(hwiNum, pri) \
do { \
*(volatile U8 *)((uintptr_t)OS_NVIC_PRI_BASE + (hwiNum)) = (U8)(pri); \
} while (0)
/* 设置异常优先级 */
#define NVIC_SET_EXC_PRI(excNum, pri) \
do { \
*(volatile U8 *)((uintptr_t)OS_NVIC_EXCPRI_BASE + ((excNum) - 4)) = (U8)(pri); \
} while (0)
/* 清除悬起中断位 */
#define NVIC_CLR_IRQ_PEND(hwiNum) \
do { \
*(volatile U32 *)((uintptr_t)OS_NVIC_CLRPEND_BASE + (((hwiNum) >> 5) << 2)) = 1UL << ((hwiNum) & 0x1FUL); \
} while (0)
/* 设置悬起中断位 */
#define NVIC_SET_IRQ_PEND(hwiNum) \
do { \
*(volatile U32 *)((uintptr_t)OS_NVIC_SETPEND_BASE + (((hwiNum) >> 5) << 2)) = 1UL << ((hwiNum) & 0x1FUL); \
} while (0)
#endif /* PRT_HWI_INTERNAL_H */
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: tick后处理调度文件。
*/
#include "prt_sys_external.h"
OS_SEC_ALW_INLINE INLINE void OsTickBh(void)
{
uintptr_t intSave;
while (TICK_NO_RESPOND_CNT > 0) {
TICK_NO_RESPOND_CNT--;
UNI_FLAG |= OS_FLG_TICK_ACTIVE;
/* 整个调度过程中就是关中断的 */
intSave = PRT_HwiUnLock();
/* 如果tick未初始化,TICK_NO_RESPOND_CNT=0,故不会进入此处,调用tick后处理 */
g_tickDispatcher();
PRT_HwiRestore(intSave);
UNI_FLAG &= ~OS_FLG_TICK_ACTIVE;
}
}
OS_SEC_TEXT void OsViDispatch(void)
{
/* tick 后处理的调度 */
if ((UNI_FLAG & OS_FLG_TICK_ACTIVE) != 0) {
return;
}
OsTickBh();
}
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: 属性宏相关内部头文件
*/
#ifndef OS_ATTR_ARMV7_M_EXTERNAL_H
#define OS_ATTR_ARMV7_M_EXTERNAL_H
/* 定义操作系统的代码数据分段 */
#ifndef OS_SEC_L0_TEXT
#define OS_SEC_L0_TEXT
#endif
#ifndef OS_SEC_TEXT
#define OS_SEC_TEXT
#endif
#ifndef OS_SEC_L2_TEXT
#define OS_SEC_L2_TEXT
#endif
#ifndef OS_SEC_L4_TEXT
#define OS_SEC_L4_TEXT
#endif
#ifndef OS_SEC_DATA
#define OS_SEC_DATA
#endif
#ifndef OS_SEC_L4_DATA
#define OS_SEC_L4_DATA
#endif
#ifndef OS_SEC_BSS
#define OS_SEC_BSS
#endif
#ifndef OS_SEC_L4_BSS
#define OS_SEC_L4_BSS
#endif
#ifndef VEC_SEC_DATA
#define VEC_SEC_DATA __attribute__((section("VECTOR")))
#endif
#endif /* OS_ATTR_ARMV7_M_EXTERNAL_H */
@@ -0,0 +1,146 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: mem模块的模块内头文件
*/
#ifndef OS_CPU_ARMV7_M_EXTERNAL_H
#define OS_CPU_ARMV7_M_EXTERNAL_H
#include "prt_buildef.h"
#include "prt_hwi.h"
#include "prt_clk.h"
#define OS_MAX_CACHE_LINE_SIZE 4 /* 单核芯片定义为4 */
#define OS_MX_SYS_VECTOR_CNT 16 /* 系统向量个数 16 */
#define OS_HWI_PRI_INVALID_BYTE 4 /* 芯片优先级无效位数 */
/* M4支持中断嵌套,需要设置PRIGROUP = 0, 表达抢占优先级的位段[7:1],表达子优先级的位段[0:0] */
/* 初始化中断优先级组,[1,7]都为抢占优先级位断 */
#define OS_NVIC_AIRCR_PRIGROUP 6
/* 初始化中断优先级组 */
#define OS_HWI_MAX_PRI 0x8 /* 高抢占优先级留给SVC中断 */
#define OS_HWI_PRI_HIGHEST 0x00
#define OS_HWI_PRI_LOWEST 0xF0
#define OS_MX_VECTOR_CNT (OS_MX_SYS_VECTOR_CNT + OS_MX_IRQ_VECTOR_CNT) /* 系统向量16个 + 60(M3)/82(M4)个中断向量 */
#define OS_HWI_PRI_SHIELD_HIGH 0x80 /* 屏蔽高位 */
#define OS_HWI_SET_HOOK_ATTR(hwiNum, hwiPrio, hook)
#define OS_HWI_PRIO_CHECK(hwiPrio) ((hwiPrio) >= OS_HWI_MAX_PRI)
/* 为了保持对外接口统一(硬件中断号),mx的hwinum=irqnum=真实中断号-16(内部已处理, 见OsInterrupt) */
#define OS_IRQ2HWI(irqNum) (irqNum)
#define OS_HWI2IRQ(hwiNum) (hwiNum)
#define OS_HWI_GET_HWINUM(archNum) (archNum)
#define OS_HWI_GET_HWI_PRIO(hwiPrio) (((hwiPrio) << OS_HWI_PRI_INVALID_BYTE) | OS_HWI_PRI_SHIELD_HIGH)
#define OS_HWI_GET_USER_PRIO(hwiPrio) (((hwiPrio) & (~OS_HWI_PRI_SHIELD_HIGH)) >> OS_HWI_PRI_INVALID_BYTE)
#define OS_TICK_COUNT_UPDATE() \
do { \
(void)PRT_ClkGetCycleCount64(); \
} while (0)
extern U32 OsTickTimerStartMx(U32 cyclePerTick);
#define OS_HW_TICK_INIT() OsTickTimerStartMx(g_cyclePerTick)
/* 检查cyclepertick是否超出寄存器范围 */
#define OS_IS_TICK_PERIOD_INVALID(cyclePerTick) ((cyclePerTick) > 0x00FFFFFF || (cyclePerTick) == 0)
/*
* 模块间宏定义
*/
#define OS_TSK_STACK_ADDR_ALIGN 16
#define OS_TSK_STACK_SIZE_ALIGN 16
#define OS_TSK_STACK_SIZE_ALLOC_ALIGN MEM_ADDR_ALIGN_016
/* 任务栈最小值 */
#define OS_TSK_MIN_STACK_SIZE (ALIGN((0x130), 16))
/* Idle任务的消息队列数 */
#define OS_IDLE_TASK_QUE_NUM 1
extern U64 OsU64DivGetQuotient(U64 dividend, U64 divisor);
extern U64 OsU64DivGetRemainder(U64 dividend, U64 divisor);
#define DIV64(a, b) OsU64DivGetQuotient((a), (b))
#define DIV64_REMAIN(a, b) OsU64DivGetRemainder((a), (b))
/*
* 任务上下文的结构体定义。
*/
struct TagHwContext {
U32 r4;
U32 r5;
U32 r6;
U32 r7;
U32 r8;
U32 r9;
U32 r10;
U32 r11;
U32 basePri;
U32 excReturn;
U32 r0;
U32 r1;
U32 r2;
U32 r3;
U32 r12;
U32 lr;
U32 pc;
U32 psr;
};
#define OsIntUnLock() PRT_HwiUnLock()
#define OsIntLock() PRT_HwiLock()
#define OsIntRestore(intSave) PRT_HwiRestore(intSave)
#define OsTaskTrap() OsTaskSwitch()
#define OsHwiTrap() OsHwiSwitch()
/*
* 模块间内联函数定义
*/
OS_SEC_ALW_INLINE INLINE U32 OsGetHwThreadId(void)
{
return 0x0U;
}
OS_SEC_ALW_INLINE INLINE uintptr_t OsMemAddrToUncache(uintptr_t addr)
{
return addr;
}
extern U32 OsGetSp(void);
extern U32 OsIntNumGet(void);
extern void OsTaskSwitch(void);
extern void OsHwiSwitch(void);
extern void OsTickIsr(void);
OS_SEC_ALW_INLINE INLINE void OsTaskTrapFast(void)
{
OsTaskTrap();
}
OS_SEC_ALW_INLINE INLINE void OsTaskTrapFastPs(uintptr_t intSave)
{
(void)intSave;
OsTaskTrap();
}
/* 传入任务切换时的栈地址 */
OS_SEC_ALW_INLINE INLINE uintptr_t OsTskGetInstrAddr(uintptr_t addr)
{
return ((struct TagHwContext *)addr)->pc;
}
#define OS_SPIN_LOCK_INIT(lockVar)
#if (OS_HARDWARE_PLATFORM == OS_CORTEX_M4)
#include "../cortex-m4/prt_cpu_m4_external.h"
#endif
#endif /* OS_CPU_ARMV7_M_EXTERNAL_H */
+51
View File
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-07-24
* Description: Hardware Initialization
*/
#include "prt_cpu_external.h"
#define OS_CPSR_REG_DEFAULT_VAL 0x01000000U
#define OS_EXCRETURN_DEFAULT_VAL 0xFFFFFFFDU
OS_SEC_L4_TEXT void *OsTskContextInit(U32 taskId, U32 stackSize, uintptr_t *topStack, uintptr_t funcTskEntry)
{
uintptr_t endStack;
struct TagHwContext *context = NULL;
/*
* O0优化情况下,子函数会自动将父函数的栈指针,压入到父函数栈顶+4
* 处,根函数没有父函数,需要构造虚拟父函数,预留16字节空间,
* 未使用的空间作为维测使用
* O2优化情况下,编译器生成指令不会进行上述操作,每个任务的栈底预留16
* 个字节均初始化魔术字,作为维测使用,以判断是否有任务从栈底溢出
*/
endStack = TRUNCATE((uintptr_t)topStack + stackSize, OS_TSK_STACK_ADDR_ALIGN);
context = (struct TagHwContext *)(endStack - sizeof(struct TagHwContext));
/* 初始化任务上下文 */
*context = (struct TagHwContext){0};
// 配置寄存器默认初值
context->basePri = 0;
context->excReturn = OS_EXCRETURN_DEFAULT_VAL;
/* 任务的第一个参数 */
context->r0 = taskId;
context->lr = 0;
context->pc = (uintptr_t)funcTskEntry;
context->psr = OS_CPSR_REG_DEFAULT_VAL; /* bit20表示thumb指令 */
return (void *)context;
}
OS_SEC_L4_TEXT void OsTskContextGet(uintptr_t saveAddr, struct TskContext *context)
{
*context = *((struct TskContext *)saveAddr);
}
@@ -0,0 +1,2 @@
add_library(prt_hw_tick OBJECT prt_hw_tick.c)
add_library(prt_hw_tick_minor OBJECT prt_hw_tick_minor.c)
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: Tick interrupt implementation
*/
#include "prt_hw_tick_internal.h"
/* 系统当前运行的时间,单位cycle */
OS_SEC_BSS U64 g_cycleNow;
/* 在tick中记录的系统当前cycle值 */
OS_SEC_BSS U64 g_cycleInTick;
/* 系统当前运行的时间,时间是g_cyclePerTick的整数倍 */
OS_SEC_BSS U64 g_cycleByTickNow;
OS_SEC_TEXT void OsTickIsr(void)
{
uintptr_t intSave;
intSave = PRT_HwiLock();
TICK_NO_RESPOND_CNT++;
/* 调用CycleUpdate更新g_cycleNow g_cycleByTickNow */
OsCycleUpdate();
PRT_HwiRestore(intSave);
OsHwiTrap();
}
/*
* 描述:设置Tick硬件定时器定时时长,使能Tick中断定时器
*/
OS_SEC_TEXT void OsTickStartRegSet(U16 tickHwTimerIndex, U32 cyclePerTick)
{
(void)tickHwTimerIndex;
g_cycleByTickNow = 0;
g_cycleInTick = 0;
TICK_NO_RESPOND_CNT = 0;
/* 系统初始化的时候将其初始化为0,因为初始化时为关中断,不会响应tick中断,只有在切换到多线程的模式才会开始计数 */
g_uniTicks = 0;
/* M3时钟计数寄存器,当计数到0时,该值会被重新装载 */
*(volatile U32 *)OS_SYSTICK_RELOAD_REG = cyclePerTick;
/*
* M4时钟控制寄存器: bit0为使能位,1表示使能;bit1为计数减为0
* 时是否产生中断源,1表示产生中断;bit2为使用内部时钟还是外部时钟,1表示未内部时钟
*/
*(volatile U32 *)OS_SYSTICK_CONTROL_REG = OS_BIT0_MASK | OS_BIT1_MASK | OS_BIT2_MASK;
}
OS_SEC_L4_TEXT U32 OsTickTimerStartMx(U32 cyclePerTick)
{
OsTickStartRegSet(0, cyclePerTick);
return OS_OK;
}
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: hw模块内部头文件。
*/
#ifndef PRT_HW_TICK_INTERNAL_H
#define PRT_HW_TICK_INTERNAL_H
#include "prt_lib_external.h"
#include "prt_sys_external.h"
#include "prt_tick_external.h"
/* 系统当前运行的时间,单位cycle */
extern U64 g_cycleNow;
/* 在tick中记录的系统当前cycle值 */
extern U64 g_cycleInTick;
/* 系统当前运行的时间,时间是g_cyclePerTick的整数倍 */
extern U64 g_cycleByTickNow;
/*
* 模块内宏定义
*/
#define OS_SYSTICK_CONTROL_COUNTFLAG_MSK (1U << 16)
#define OS_SYSTICK_CONTROL_REG 0xE000E010
#define OS_SYSTICK_RELOAD_REG 0xE000E014
#define OS_SYSTICK_CURRENT_REG 0xE000E018
/*
* 模块间函数声明
*/
extern void OsCycleUpdate(void);
#endif /* PRT_HW_TICK_INTERNAL_H */
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: 硬件tick模块的C文件。
*/
#include "prt_hw_tick_internal.h"
/*
* 描述:CycleUpdate内部函数,该接口必须关中断情况下调用
*/
OS_SEC_L2_TEXT void OsCycleUpdate(void)
{
U32 hwCycleFirst; /* PosA */
U32 hwCycleCtrl; /* PosB */
U32 hwCycleSecond; /* PosC */
/*
* 此处关中断后SysTick 中断上报会发生在以上四个时机
* 1), Before PosA then CONTROL_COUNTFLAG will be set and hwCycleFirst >= hwCycleSecond
* 2), Between PosA and PosB then CONTROL_COUNTFLAG will be set and hwCycleFirst < hwCycleSecond
* 3), Between PosB and PosC then CONTROL_COUNTFLAG will be clear and hwCycleFirst < hwCycleSecond
* 4), After PosC we'll see it next time
*/
hwCycleFirst = *(volatile U32 *)OS_SYSTICK_CURRENT_REG;
hwCycleCtrl = *(volatile U32 *)OS_SYSTICK_CONTROL_REG;
hwCycleSecond = *(volatile U32 *)OS_SYSTICK_CURRENT_REG;
/* 如果1、装载值前一次比后一次小 或 2、OS_SYSTICK_CONTROL_COUNTFLAG 已经SET */
/* 则 说明tick反转,需要手动补偿一个周期 */
if (((hwCycleCtrl & OS_SYSTICK_CONTROL_COUNTFLAG_MSK) != 0) || (hwCycleFirst < hwCycleSecond)) {
g_cycleByTickNow += OsGetCyclePerTick();
/* 再一次读时钟定时器,读清COUNTFLAG位 */
/* COUNTFLAG位(bit16)Returns 1 If Timer Counted To 0 Since Last Time This Was Read */
(void)*(volatile U32 *)OS_SYSTICK_CONTROL_REG;
}
g_cycleNow = (g_cycleByTickNow + (OsGetCyclePerTick() - hwCycleSecond));
}
OS_SEC_L2_TEXT U64 PRT_ClkGetCycleCount64(void)
{
U64 cycle;
uintptr_t intSave;
intSave = PRT_HwiLock();
OsCycleUpdate();
cycle = g_cycleNow;
PRT_HwiRestore(intSave);
return cycle;
}
@@ -0,0 +1,10 @@
set(CMAKE_ASM_COMPILER_ID "ARMASM")
add_library(prt_hw OBJECT prt_hw.S)
set_target_properties(prt_hw PROPERTIES OUTPUT_NAME "prt_hw") #对目标文件重命名
add_library(prt_hw_exc OBJECT prt_hw_exc.S)
set_target_properties(prt_hw_exc PROPERTIES OUTPUT_NAME "prt_hw_exc") #对目标文件重命名
add_library(prt_dispatch OBJECT prt_dispatch.S)
set_target_properties(prt_dispatch PROPERTIES OUTPUT_NAME "prt_dispatch") #对目标文件重命名
add_library(prt_vector OBJECT prt_vector.S)
set_target_properties(prt_vector PROPERTIES OUTPUT_NAME "prt_vector") #对目标文件重命名
add_library(prt_div64 OBJECT prt_div64.c)
+4
View File
@@ -0,0 +1,4 @@
menu "M4 Sepecfic Configuration"
depends on INTERNAL_OS_PLATFORM_M4
endmenu
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-07-24
* Description: Macros used in assembly code
*/
#ifndef PRT_CPU_M4_EXTERNAL_H
#define PRT_CPU_M4_EXTERNAL_H
#include "prt_typedef.h"
/*
* 模块间typedef声明
*/
typedef void (*HwiPubintFunc)(void);
#define OS_MX_IRQ_VECTOR_CNT 150
#if defined(OS_OPTION_HWI_MAX_NUM_CONFIG)
extern U32 g_hwiMaxNumConfig;
#define OS_HWI_MAX_NUM g_hwiMaxNumConfig
#else
#define OS_HWI_MAX_NUM 87
#define OS_HWI_FORMARRAY_NUM OS_HWI_MAX_NUM
#endif
#define OS_HWI_MAX (OS_HWI_MAX_NUM - 1) /* 最大中断号 */
#define OS_HWI_NUM_CHECK(hwiNum) ((hwiNum) > OS_HWI_MAX)
extern void g_stackEnd(void);
extern U32 g_stackStart;
#define MSTACK_VECTOR g_stackEnd
OS_SEC_ALW_INLINE INLINE uintptr_t OsGetSysStackTop(void)
{
return (uintptr_t)(&g_stackStart);
}
OS_SEC_ALW_INLINE INLINE uintptr_t OsGetSysStackBottom(void)
{
return (uintptr_t)g_stackEnd;
}
/*
* 描述:检查配置的最大中断个数是否合法,合法返回TRUE
*/
OS_SEC_ALW_INLINE INLINE bool OsHwiCheckMaxNum(U32 maxNum)
{
return ((maxNum > 0) && (maxNum <= OS_MX_IRQ_VECTOR_CNT));
}
#endif /* PRT_CPU_M4_EXTERNAL_H */
@@ -0,0 +1,329 @@
@/*
@ * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
@ *
@ * UniProton is licensed under Mulan PSL v2.
@ * You can use this software according to the terms and conditions of the Mulan PSL v2.
@ * You may obtain a copy of Mulan PSL v2 at:
@ * http://license.coscl.org.cn/MulanPSL2
@ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
@ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
@ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
@ * See the Mulan PSL v2 for more details.
@ * Create: 2009-07-24
@ * Description: thread scheduler
@ */
.align 8
.global PRT_HwiLock
.global PRT_HwiUnLock
.global PRT_HwiRestore
.global OsFirstTimeSwitch
.global OsTaskSwitch
.global OsHwiSwitch
.global OsPendSv
.global OsIntNumGet
.global OsSvchandler
.global OsRestoreGeneralR
.global OsTaskSwtichHook
.global OsViSwitchRet
.type PRT_HwiLock, function
.type PRT_HwiUnLock, function
.type PRT_HwiRestore, function
.type OsFirstTimeSwitch, function
.type FirstTaskSwtich,function
.type OsIntNumGet, function
.type OsTaskSwitch, function
.type OsHwiSwitch,function
.type OsSvchandler, function
.type OsPendSv, function
.type OsGoViDispatch,function
.type OsViSwitchRet, function
.type OsVi2Task,function
.type OsTaskContexSave,function
.type OsRestoreGeneralR, function
.type OsTaskSwtich,function
.type OsTaskLoad,function
.type OsNotLoadFloat,function
.type OsTaskEnd,function
.type OsTaskSwtichHook,function
.type OsViDispatch,function
.extern g_runningTask
.extern g_highestTask
.extern g_stackEnd
.extern g_uniFlag
.extern OsViDispatch
.extern g_tickNoRespondCnt
.extern g_excTrap
.extern OsTskSwitchHookCaller
OS_NVIC_INT_CTRL = 0xE000ED04
OS_NVIC_SYSPRI2 = 0xE000ED20
OS_NVIC_PENDSV_PRI = 0xF0F00000
OS_NVIC_PENDSVSET = 0x10000000
OS_TSK_RUNNING = 0x0080
OS_INT_HIGHEST_LEVEL = 0x80
OS_INT_LOWEST_LEVEL = 0x00
OS_EXC_RETURN_TM_MSP = 0xFFFFFFF9
@exc return flag
OS_FPU_SAVE_FLAG = 0x10
OS_SP_SELECT_FLAG = 0x04
@hardware push SP len
OS_FPU_PUSH_SP_AUTO = 104
OS_NORMAL_PUSH_SP_AUTO = 32
@switch flag
OS_SVC_TSK_SWICH = 1
OS_SVC_VI2TASK = 2
OS_FLG_BGD_ACTIVE = 0x0002
OS_FLG_SYS_ACTIVE = 0x0010
OS_FLG_TSK_REQ = 0x1000
OS_FLG_TSK_SWHK = 0x2000
OS_VI_XPSR = 0x01000000
.section .text, "ax"
.thumb
.syntax unified
OsFirstTimeSwitch:
LDR R4, =OS_NVIC_SYSPRI2
LDR R5, =OS_NVIC_PENDSV_PRI
STR R5, [R4]
@ reset MSP
LDR R0, =g_stackEnd
MSR MSP, R0
FirstTaskSwtich:
@use PSP in thread mode from now
MOV R0, #2
MSR CONTROL, R0
@g_uniFlag
LDR R0, =g_uniFlag
LDR R1, [R0]
ORR R1, R1,#OS_FLG_BGD_ACTIVE
STR R1, [R0]
@g_runningTask = g_highestTask
LDR R0, =g_highestTask
LDR R0, [R0]
LDR R1, =g_runningTask
STR R0, [R1]
@g_runningTask->taskStatus |= OS_TSK_RUNNING
LDRH R1, [R0, #4]
ORR R1, R1, #OS_TSK_RUNNING
STRH R1, [R0, #4]
@ get func parameter from stack
LDR R1, [R0]
ADD R1, R1, #40
LDR R5, [R1]
@get LR,PC,XPSR from stack
ADD R1, R1, #20
LDMFD R1!, {R2-R4}
MSR PSP, R1
MOV LR, R2
MSR xPSR, R4
MOV R0, R5
CPSIE I
BX R3
.align
.section .kernel, "ax"
.thumb
.syntax unified
PRT_HwiLock:
MRS R0, BASEPRI
MOV R1, #OS_INT_HIGHEST_LEVEL
MSR BASEPRI, R1
BX LR
PRT_HwiUnLock:
MRS R0, BASEPRI
MOV R1, #OS_INT_LOWEST_LEVEL
MSR BASEPRI, R1
BX LR
PRT_HwiRestore:
MSR BASEPRI, R0
BX LR
OsIntNumGet:
MRS R0, IPSR
BX LR
OsTaskSwitch:
SVC #OS_SVC_TSK_SWICH
BX LR
OsHwiSwitch:
LDR R0, =OS_NVIC_INT_CTRL
LDR R1, =OS_NVIC_PENDSVSET
STR R1, [R0]
BX LR
OsSvchandler:
TST LR, #OS_SP_SELECT_FLAG
ITE EQ
MRSEQ R0, MSP
MRSNE R0, PSP
@get pc
LDR R1, [R0,#24]
@get svc instruction
LDRB R0, [R1,#-2]
CMP R0, #OS_SVC_TSK_SWICH
BEQ OsPendSv
CMP R0, #OS_SVC_VI2TASK
BEQ OsVi2Task
@ excpetion
LDR R1, =g_excTrap
LDR R1, [R1]
CMP R1, #0
BXNE R1
B .
OsPendSv:
MRS R12, BASEPRI
MOV R2, #OS_INT_HIGHEST_LEVEL
MSR BASEPRI, R2
@tick switch
LDR R0, =g_tickNoRespondCnt
LDR R3, [R0]
CMP R3, #0
BNE OsGoViDispatch
@task switch
B OsTaskContexSave
OsGoViDispatch:
push {R12,LR}
@call tick dispatch
LDR R3, =OS_VI_XPSR
LDR R2, =OsViDispatch
LDR R1, =OsViSwitchRet
push {R1-R3}
sub sp,sp,#20
@thread mode msp
MOV LR, #OS_EXC_RETURN_TM_MSP
BX LR
OsViSwitchRet:
SVC #OS_SVC_VI2TASK
B .
OsVi2Task:
TST LR, #OS_FPU_SAVE_FLAG
ITE EQ
MOVEQ R2, #OS_FPU_PUSH_SP_AUTO
MOVNE R2, #OS_NORMAL_PUSH_SP_AUTO
ADD SP, SP, R2
pop {R12, LR}
OsTaskContexSave:
TST LR, #OS_SP_SELECT_FLAG
BEQ OsTaskEnd
@save task context
LDR R0, =g_uniFlag
LDR R1, [R0]
MOV R3, R1
BIC R1, R1, #OS_FLG_TSK_REQ /* g_uniFlag &= ~OS_FLG_TSK_REQ */
STR R1, [R0]
TST R3, #OS_FLG_TSK_REQ
BEQ OsTaskEnd
@get PSP
MRS R0, PSP
@Is the task using the FPU context? If so, push high vfp registers.
TST LR, #OS_FPU_SAVE_FLAG
BNE OsRestoreGeneralR
@store s16-s31
VSTMDB R0!, {S16-S31}
OsRestoreGeneralR:
@store R4-R11,BASEPRI,EXC_RETURN
STMFD R0!, {R4-R12, LR}
@g_runningTask->stackPointer = PSP
LDR R5, =g_runningTask
LDR R6, [R5]
STR R0, [R6]
@g_runningTask->taskStatus &= ~OS_TSK_RUNNING
LDRH R1, [R6, #4]
BIC R1, R1, #OS_TSK_RUNNING
STRH R1, [R6, #4]
@get new task
LDR R7, =g_highestTask
LDR R7, [R7]
OsTaskSwtich:
@g_runningTask = g_highestTask
STR R7, [R5]
@g_runningTask->taskStatus |= OS_TSK_RUNNING
LDRH R1, [R7, #4]
ORR R1, R1, #OS_TSK_RUNNING
STRH R1, [R7, #4]
@task switch hook,dot not change R5 R6 R7
LDR R0, =g_uniFlag
LDR R1, [R0]
TST R1, #OS_FLG_TSK_SWHK
BNE OsTaskSwtichHook
OsTaskLoad:
@load R4-R11,BASEPRI,EXC_RETURN
LDR R1, [R7]
LDMFD R1!, {R4-R12,LR}
TST LR, #OS_FPU_SAVE_FLAG
BNE OsNotLoadFloat
@load s16-s31
VLDMIA R1!, {S16-S31}
OsNotLoadFloat:
MSR PSP, R1
OsTaskEnd:
MSR BASEPRI, R12
@auto restore R0-R3,R12,lr,pc,xpsr
BX LR
OsTaskSwtichHook:
LDR R3, =OsTskSwitchHookCaller
LDR R0, [R6, #16]
LDR R1, [R7, #16]
LDR LR, =OsTaskLoad
BX R3
.align
.end
@@ -0,0 +1,97 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-07-25
* Description: 64位除法文件。
*/
#include "prt_typedef.h"
#include "prt_lib_external.h"
#include "prt_attr_external.h"
#define OS_32_BITS_COUNT 32
/*
* 描述:前导0个数获取
*/
OS_SEC_TEXT U32 OsleadingZeroCount(U64 data)
{
U32 high = (U32)OS_GET_64BIT_HIGH_32BIT(data);
U32 low = (U32)OS_GET_64BIT_LOW_32BIT(data);
U32 count = 0;
if (high == 0) {
OS_EMBED_ASM("CLZ %0, %1" : "=r"(count) : "r"(low));
count += OS_32_BITS_COUNT;
} else {
OS_EMBED_ASM("CLZ %0, %1" : "=r"(count) : "r"(high));
}
return count;
}
OS_SEC_TEXT void OsU64Div(U64 dividend, U64 divisor, U64 *quotient, U64 *remainder)
{
U32 alignShift;
U32 i;
U64 tmpDivisor;
U64 tmpRemainder;
U64 tmpQuotient = 0;
if (divisor == 0) {
return; // 除数为0返回1
}
if (dividend < divisor) {
/* 被除数小于除数,商为0,余数即被除数 */
*remainder = dividend;
*quotient = 0;
return;
}
alignShift = OsleadingZeroCount(divisor) - OsleadingZeroCount(dividend);
tmpDivisor = divisor << alignShift;
tmpRemainder = dividend;
/* 竖式除法, 类大数相除 */
for (i = 0; i <= alignShift; i++) {
tmpQuotient <<= 1;
if (tmpRemainder >= tmpDivisor) {
tmpRemainder -= tmpDivisor;
tmpQuotient += 1;
}
tmpDivisor >>= 1;
}
*quotient = tmpQuotient;
*remainder = tmpRemainder;
return;
}
OS_SEC_TEXT U64 OsU64DivGetQuotient(U64 dividend, U64 divisor)
{
U64 quotient = 0;
U64 remainder;
OsU64Div(dividend, divisor, &quotient, &remainder);
return quotient;
}
OS_SEC_TEXT U64 OsU64DivGetRemainder(U64 dividend, U64 divisor)
{
U64 quotient;
U64 remainder = 0;
OsU64Div(dividend, divisor, &quotient, &remainder);
return remainder;
}
+54
View File
@@ -0,0 +1,54 @@
@/*
@ * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
@ *
@ * UniProton is licensed under Mulan PSL v2.
@ * You can use this software according to the terms and conditions of the Mulan PSL v2.
@ * You may obtain a copy of Mulan PSL v2 at:
@ * http://license.coscl.org.cn/MulanPSL2
@ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
@ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
@ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
@ * See the Mulan PSL v2 for more details.
@ * Create: 2009-12-22
@ * Description: thread scheduler
@ */
.align 8
.section .text, "ax"
.thumb
.syntax unified
.global OsAsmIll
.global OsGetSp
.global OsFpuInit
.type OsAsmIll, function
.type OsGetSp, function
.type OsFpuInit,function
OS_EXC_CAUSE_FATAL_ERR = 18
OsAsmIll:
SVC OS_EXC_CAUSE_FATAL_ERR
LOOP:
B LOOP
OsGetSp:
MRS R0, PSP @ 读取PSP
BX LR
OsFpuInit:
LDR R0, = 0xE000ED88 @ Enable CP10, CP11
LDR R1, [R0]
ORR R1, R1, #(0xF << 20)
STR R1, [R0]
LDR R0, = 0xE000EF34 @ FPU is automatic save or store mode
LDR R1, [R0]
AND R1, R1, #0XBFFFFFFF
ORR R1, R1, #0X80000000
STR R1, [R0]
BX LR
.align
.end
+278
View File
@@ -0,0 +1,278 @@
@/*
@ * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
@ *
@ * UniProton is licensed under Mulan PSL v2.
@ * You can use this software according to the terms and conditions of the Mulan PSL v2.
@ * You may obtain a copy of Mulan PSL v2 at:
@ * http://license.coscl.org.cn/MulanPSL2
@ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
@ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
@ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
@ * See the Mulan PSL v2 for more details.
@ * Create: 2009-12-22
@ * Description: exc汇编文件
@ */
.align 8
.section .text, "ax"
.thumb
.syntax unified
.global OsExcNmi
.global OsExcHardFault
.global OsExcMemFault
.global OsExcBusFault
.global OsExcUsageFault
.global OsExcSvcCall
.type OsExcNmi, function
.type OsExcHardFault, function
.type OsExcMemFault, function
.type OsExcBusFault, function
.type OsExcUsageFault, function
.type OsExcSvcCall, function
.extern OsExcHandleEntryM4
.extern g_uniFlag
.extern g_curNestCount
OS_FLG_BGD_ACTIVE = 0x0002
OS_FLG_MSP_ACTIVE = 0x001D
@exc return using floating-point state flag
OS_FPU_SAVE_FLAG = 0x10
@hardware push SP len
OS_FPU_PUSH_SP_AUTO = 104 @auto save 18 float registers(S0~S15,CPSR,REV,SP 8bytes align) add 8 normal R registers,(18 + 8) * 4
OS_NORMAL_PUSH_SP_AUTO = 32 @auto save 8 normal R registers(xPSR, PC, LR, R12,R0~R3),8*4
@exception type
NO_BMU_FAULT = 0
BF_STKERR = 1
BF_UNSTKERR = 2
BF_IMPRECISERR = 3
BF_PRECISERR = 4
BF_IBUSERR = 5
MF_MSTKERR = 6
MF_MUNSTKERR = 7
MF_DACCVIOL = 8
MF_IACCVIOL = 9
UF_DIVBYZERO = 10
UF_UNALIGNED = 11
UF_NOCP = 12
UF_INVPC = 13
UF_INVSTATE = 14
UF_UNDEFINSTR = 15
OS_EXC_CAUSE_NMI = 16
OS_EXC_CAUSE_HARDFAULT = 17
HF_DBGEVT = 19
HF_VECTBL = 20
FLAG_ADDR_VALID = 0x10000
@if bit2 = 1,then ret use psp
OS_FALG_EXC_RET_PSP_STATUS = 0x4
@UsageFault:0x030F; BusFault:0x1F(clear BFARVALID bit); MemFault:0x1B(clear MMARVALID bit)
OS_BMU_FAULT_CLEAR_BIT = 0x030F1F1B
@Fault Reg valid exception bit
OS_BMU_FAULT_VALID_BIT = 0x030F9F9B
OS_HARD_FAULT_VAILD_BIT = 0xC0000002
OS_NVIC_FSR = 0xE000ED28 @include BusFault/MemFault/UsageFault State Regeister
OS_NVIC_HFSR = 0xE000ED2C @HardFault State Regeister
OS_NVIC_BFAR = 0xE000ED38
OS_NVIC_MMAR = 0xE000ED34
OS_NVIC_ACT_BASE = 0xE000E300
excTbl:
.byte 0,0,0,0,0,0,UF_DIVBYZERO,UF_UNALIGNED
.byte 0,0,0,0,UF_NOCP,UF_INVPC,UF_INVSTATE,UF_UNDEFINSTR
.byte 0,0,0,BF_STKERR,BF_UNSTKERR,BF_IMPRECISERR,BF_PRECISERR,BF_IBUSERR
.byte 0,0,0,MF_MSTKERR,MF_MUNSTKERR,0,MF_DACCVIOL,MF_IACCVIOL
.byte NO_BMU_FAULT,0,0,0
OsExcNmi:
MOV R0, #OS_EXC_CAUSE_NMI
MOV R1, #0
B OsExcDispatch
OsExcHardFault:
MOV R0, #OS_EXC_CAUSE_HARDFAULT
LDR R2, =OS_NVIC_HFSR
LDR R2, [R2]
MOV R1, #HF_DBGEVT
LSL R1, R1, #0x8
ORR R0, R1
TST R2, #0x80000000
BNE OsExcDispatch @ DBGEVT
AND R0, #0x000000FF
MOV R1, #HF_VECTBL
LSL R1, R1, #0x8
ORR R0, R1
TST R2, #0x00000002 @ bit1 indicates the fault of VECTBL
BNE OsExcDispatch @ VECTBL
@if not DBGEVT and VECTBL then is FORCED
AND R0, #0x000000FF
LDR R2, =OS_NVIC_FSR
LDR R2, [R2]
TST R2, #0x8000 @ BFARVALID
BNE _HFBusFault @ BusFault
TST R2, #0x80 @ MMARVALID
BNE _HFMemFault @ MemFault
MOV R12,#0
B OsHFExcCommonBMU
_HFBusFault:
LDR R1, =OS_NVIC_BFAR
LDR R1, [R1]
MOV R12, #FLAG_ADDR_VALID
B OsHFExcCommonBMU
_HFMemFault:
LDR R1, =OS_NVIC_MMAR
LDR R1, [R1]
MOV R12, #FLAG_ADDR_VALID
OsHFExcCommonBMU:
LDR R3, =OS_BMU_FAULT_CLEAR_BIT
AND R2, R3
CLZ R2, R2 @ NO_BMU_FAULT,when hard fault happen, no BMU fault(CFSR(R2) = 0, CLZ R2, R2 -> R2 = 32)
LDR R3, =excTbl
ADD R3, R3, R2
LDRB R2, [R3]
LSL R2, R2, #0x8 @ORR R0, R2, LSL #0x8
ORR R0, R2
ORR R0, R12
B OsExcDispatch
OsExcSvcCall:
TST LR, #0x4 @exc_return bit2
MRSEQ R0, MSP @msp->R0
MRSNE R0, PSP @psp->R0
LDR R1, [R0,#24] @exc pc->R1
LDRB R0, [R1,#-2] @get para0 from instrution SVC
MOV R1, #0
B OsExcDispatch
OsExcBusFault:
LDR R0, =OS_NVIC_FSR
LDR R0, [R0]
TST R0, #0x8000 @ BFARVALID
BEQ _ExcBusNoADDR
LDR R1, =OS_NVIC_BFAR
LDR R1, [R1]
MOV R12, #FLAG_ADDR_VALID
B OsExcCommonBMU
_ExcBusNoADDR:
MOV R12,#0
B OsExcCommonBMU
OsExcMemFault:
LDR R0, =OS_NVIC_FSR
LDR R0, [R0]
TST R0, #0x80 @ MMARVALID
BEQ _ExcMemNoADDR
LDR R1, =OS_NVIC_MMAR
LDR R1, [R1]
MOV R12, #FLAG_ADDR_VALID
B OsExcCommonBMU
_ExcMemNoADDR:
MOV R12,#0
B OsExcCommonBMU
OsExcUsageFault:
LDR R0, =OS_NVIC_FSR
LDR R0, [R0]
@clear UsageFault invalid bit
MOV R12, #0
OsExcCommonBMU:
LDR R3, =OS_BMU_FAULT_CLEAR_BIT
AND R0, R3
CLZ R0, R0
LDR R3, =excTbl
ADD R3, R3, R0
LDRB R0, [R3]
ORR R0, R0, R12
@ R0 -- EXCCAUSE(bit 16 is 1 if EXCADDR valid), R1 -- EXCADDR
OsExcDispatch:
@ Clear Exeption status Reg
LDR R2, =OS_NVIC_FSR
LDR R3, =OS_BMU_FAULT_VALID_BIT
STR R3, [R2]
@Clear Hardfault status Reg
LDR R2, =OS_NVIC_HFSR
LDR R3, =OS_HARD_FAULT_VAILD_BIT
STR R3, [R2]
@ exc occured in Task or Init ,interrupt, or exc
@ reserved for register info from task stack
MOV R2, R14 @MSP:LR bit2 is 0; PSP:LR bit2 is 1
TST R2, #OS_FALG_EXC_RET_PSP_STATUS
BEQ _ExcInMSP @ exc occured in MSP stack
B _ExcInPSP @ exc occured in PSP stack
_ExcInMSP:
ADD R3, R13, #OS_NORMAL_PUSH_SP_AUTO @ xPSR, PC, LR, R12,R0~R3 hardware save,8*4 bytes
TST LR, #OS_FPU_SAVE_FLAG @ Is the MSP using the floating-point state?
BNE _MspStoreExcReg
ADD R3, R13, #OS_FPU_PUSH_SP_AUTO @ xPSR, PC, LR, R12,R0~R3 and float register hardware save
_MspStoreExcReg:
PUSH {R3} @ store message-->exc: MSP(R13),save IRQ SP
MRS R12, BASEPRI @ store message-->exc: disable int?
PUSH {R4-R12} @ store message-->exc: {R4-R12}
B _handleEntry
_ExcInPSP:
@ exc occured in Task
MOV R2, R13
SUB R13, #OS_NORMAL_PUSH_SP_AUTO @ first add 8*4 Bytes Revs (for Reg. STMFD xPSR, PC, LR, R12,R0~R3)
MRS R3, PSP @ get psp
ADD R12, R3, #OS_NORMAL_PUSH_SP_AUTO @ xPSR, PC, LR, R12,R0~R3 hardware save,8*4 bytes
TST LR, #OS_FPU_SAVE_FLAG @ Is the PSP using the floating-point state?
BNE _PspStoreExcReg
ADD R12, R3, #OS_FPU_PUSH_SP_AUTO @ xPSR, PC, LR, R12,R0~R3 and float register hardware save
_PspStoreExcReg:
PUSH {R12} @ save task SP
MRS R12, BASEPRI
PUSH {R4-R12} @ save R4~R11,BASEPRI to MSP
@ copy auto saved task register(xPSR, PC, LR, R12,R0~R3)from psp stack
LDMFD R3, {R4-R11} @ R4-R11 store PSP reg(auto push xPSR, PC, LR, R12,R0~R3 when exc in task)
STMFD R2!, {R4-R11}
_handleEntry:
MOV R2, R13 @ R13:the 3th param
B OsExcHandleEntryM4
NOP
.align
.end
+180
View File
@@ -0,0 +1,180 @@
@/*
@ * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
@ *
@ * UniProton is licensed under Mulan PSL v2.
@ * You can use this software according to the terms and conditions of the Mulan PSL v2.
@ * You may obtain a copy of Mulan PSL v2 at:
@ * http://license.coscl.org.cn/MulanPSL2
@ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
@ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
@ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
@ * See the Mulan PSL v2 for more details.
@ * Create: 2009-12-22
@ * Description: thread scheduler
@ */
#include "prt_buildef.h"
#include "prt_asm_arm_external.h"
.align 8
.section .reset,"ax"
.thumb
.syntax unified
.extern g_stackEnd
.extern g_stackStart
.extern g_bssStart
.extern g_bssEnd
.extern g_hwiTable
.extern __clibrary_init
@init import exc vector table
.extern OsExcMemFault
.extern OsExcBusFault
.extern OsExcUsageFault
.extern OsExcSvcCall
.extern main
.extern PRT_HardBootInit
.global g_bootVectors
.global OsResetVector
.global OsFpuInit
.type g_bootVectors,function
.type OsResetVector,function
.type OsFpuInit,function
OS_NVIC_SHCSR = 0xE000ED24
OS_NVIC_CCR = 0xE000ED14
@Vector table offset addr
OS_NVIC_VTOR = 0xE000ED08
@Enable USGFAULT, BUSFAULT, MEMFAULT
OS_NVIC_UBM_FAULT_ENABLE = 0x70000
@Enable DIV 0, but disbale unaligned exception, because filesystem have unaligned operation
OS_NVIC_UBM_DIV_0_TRP_ENABLE = 0x10
g_bootVectors:
.long g_stackEnd
.long OsResetVector
.long OsBootNMI @system boot processs
.long OsBootHardFault @system boot processs
.long OsExcMemFault
.long OsBootNMI
.long OsExcBusFault
.long 0
.long 0
.long 0
.long 0
.long OsExcSvcCall
@ Reset handler
OsResetVector :
@disable interrupt excluding NMI and HardFault
CPSID I
@init exception
@init vector table offset reg
LDR R1, =g_stackEnd
MSR MSP, R1
LDR R0, =g_bootVectors
LDR R1, =OS_NVIC_VTOR
STR R0, [R1]
@Enable exception including USGFAULT, BUSFAULT, MEMFAULT
@*(volatile U32 *)OS_NVIC_SHCSR |= 0x70000
LDR R0, =OS_NVIC_SHCSR
LDR R1, [R0]
ORR R1, #OS_NVIC_UBM_FAULT_ENABLE
STR R1, [R0]
@Enable DIV 0 excetion
@*(volatile U32 *)OS_NVIC_CCR |= 0x10@
LDR R0, =OS_NVIC_CCR
LDR R1, [R0]
ORR R1, #OS_NVIC_UBM_DIV_0_TRP_ENABLE
STR R1, [R0]
@modify MSP to 0xCACACACA
LDR R0, =g_stackEnd @top of stack
LDR R1, =g_stackStart @bottom of stack
SUB R0, R0, R1
CMP R0, #4 @stack length <4?
BLT LOOP2
LOOP1: @the condition of stack length >=4
MOV R2, #0xCACACACA
STR R2, [R1]
ADD R1, R1, #4
SUB R0, R0, #4
CMP R0, #4
BGE LOOP1
CMP R0, #0 @four bytes align?
BEQ BSS_INIT
LOOP2: @the condition of stack length <4
MOV R2, #0xCA
STRB R2, [R1]
ADD R1, R1, #1
SUB R0, R0, #1
CMP R0, #0
BNE LOOP2
BSS_INIT:
@modify BSS to 0x0
LDR R0, =g_bssEnd
LDR R1, =g_bssStart
SUB R0, R0, R1
CMP R0, #4 @bss length <4?
BLT BSS_INIT_LOOP2
BSS_INIT_LOOP1: @the condition of bss length >=4
MOV R2, #0x0
STR R2, [R1]
ADD R1, R1, #4
SUB R0, R0, #4
CMP R0, #4
BGE BSS_INIT_LOOP1
CMP R0, #0 @four bytes align?
BEQ OsBoot
BSS_INIT_LOOP2: @the condition of bss length <4
MOV R2, #0x0
STRB R2, [R1]
ADD R1, R1, #1
SUB R0, R0, #1
CMP R0, #0
BNE BSS_INIT_LOOP2
OsBoot:
BL OsFpuInit
LDR R0, =PRT_HardBootInit
BLX R0
InitChkGuardRnd R9, R10, R11
LDR R0, =main
BX R0
OsBootNMI:
B .
OsBootHardFault:
B .
@*********************************************************************************************************
@* The function expected of the C library startup
@* code for defining the stack and heap memory locations.
@*********************************************************************************************************
@ ALIGN
@ AREA |.text|, CODE, READONLY
@
@ IMPORT __use_two_region_memory
@ EXPORT __user_initial_stackheap
@
@__user_initial_stackheap
@ LDR R0, =HeapMem
@ LDR R1, =(StackMem + Stack)
@ LDR R2, =(HeapMem + Heap)
@ LDR R3, =StackMem
@ BX LR
.align
.end
+34
View File
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-26
* Description: ARM汇编宏, 如initRnd等。
*/
#ifndef PRT_ASM_ARM_EXTERNAL_H
#define PRT_ASM_ARM_EXTERNAL_H
/*
* 描述 : stack_chk_guard支持用户传入seed写入函数宏
* argA argB argC 需要使用处传入三个可用寄存器
*/
.macro InitChkGuardRnd argA, argB, argC
ldr \argA, = g_memCanaryRdm /* 用户传入seed */
ldr \argB, = __stack_chk_guard
ldr \argC, [\argA]
cmp \argC, #0
beq 1f
str \argC, [\argB] /* RND写入 */
mov \argC, #0
str \argC, [\argA] /* 销毁 */
1:
.endm
#endif /* PRT_ASM_ARM_EXTERNAL_H */
+35
View File
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-10-05
* Description: 核架构相关的汇编宏头文件
*/
#ifndef PRT_ASM_CPU_EXTERNAL_H
#define PRT_ASM_CPU_EXTERNAL_H
/* 有名空间不支持时,从核不能从有名空间获取 */
#define GLB_NS_ADDR 0
#define GLB_NSM_START 0
#define OS_EXC_REGINFO_OFFSET 160
#define OS_EXC_MAGIC_WORD 0xEDCAACDC
#define OS_SYS_STACK_MAGIC_WORD 0xCACACACA /* 系统栈魔术字 */
/* 内核状态定义 */
#define OS_FLG_HWI_ACTIVE 0x0001
#define OS_FLG_BGD_ACTIVE 0x0002
#define OS_FLG_TICK_ACTIVE 0x0008
#define OS_FLG_SYS_ACTIVE 0x0010
#define OS_FLG_EXC_ACTIVE 0x0020
#define OS_FLG_TSK_REQ 0x1000
#define OS_FLG_TSK_SWHK 0x2000 /* 任务切换时是否调用切换入口函数 */
#endif /* PRT_ASM_CPU_EXTERNAL_H */
+24
View File
@@ -0,0 +1,24 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: 属性宏相关内部头文件
*/
#ifndef PRT_ATTR_EXTERNAL_H
#define PRT_ATTR_EXTERNAL_H
#include "prt_buildef.h"
#if defined(OS_ARCH_ARMV7_M)
#include "../cpu/armv7-m/common/os_attr_armv7_m_external.h"
#endif
#endif /* PRT_ATTR_EXTERNAL_H */
+38
View File
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-10-05
* Description: 核架构相关的头文件
*/
#ifndef PRT_CPU_EXTERNAL_H
#define PRT_CPU_EXTERNAL_H
#include "prt_task.h"
#include "prt_attr_external.h"
#define OS_GOTO_SYS_ERROR() \
do { \
OsAsmIll(); \
} while (0)
#define OS_GOTO_SYS_ERROR1() OS_GOTO_SYS_ERROR()
extern void OsAsmIll(void);
extern void OsFirstTimeSwitch(void);
extern void *OsTskContextInit(U32 taskId, U32 stackSize, uintptr_t *topStack, uintptr_t funcTskEntry);
extern void OsTskContextGet(uintptr_t saveAddr, struct TskContext *context);
extern void OsTickStartRegSet(U16 tickHwTimerIndex, U32 cyclePerTick);
#if defined(OS_ARCH_ARMV7_M)
#include "../cpu/armv7-m/common/os_cpu_armv7_m_external.h"
#endif
#endif /* PRT_CPU_EXTERNAL_H */
+42
View File
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-10-05
* Description: 异常模块的内部头文件
*/
#ifndef PRT_EXC_EXTERNAL_H
#define PRT_EXC_EXTERNAL_H
#include "prt_task.h"
#include "prt_sys.h"
#include "prt_kexc_external.h"
/* 异常类型定义 */
/* 内核进程下异常 */
#define EXC_IN_HWI 0
#define EXC_IN_TICK 1
#define EXC_IN_TASK 3
#define EXC_IN_SYS_BOOT 4
#define EXC_IN_SYS 5
/*
* 模块间typedef声明
*/
typedef void (*ExcTaskInfoFunc)(TskHandle *threadId, struct TskInfo *taskInfo);
/*
* 模块间全局变量声明
*/
// 异常时获取当前任务的信息
extern ExcTaskInfoFunc g_excTaskInfoGet;
extern void OsExcDispatch(U32 arg);
#endif /* PRT_EXC_EXTERNAL_H */
+34
View File
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: Hardware interrupt implementation
*/
#ifndef PRT_HWI_EXTERNAL_H
#define PRT_HWI_EXTERNAL_H
#include "prt_hwi.h"
#define OS_HWI_NUM_MASK 0x1FU
/*
* 模块间全局变量声明
*/
extern U8 g_hwiNum[];
/*
* 模块间函数声明
*/
extern void OsHwiGICInit(void);
extern U32 OsHwiPriorityGet(HwiHandle hwiNum);
extern void OsHwiPrioritySet(HwiHandle hwiNum, HwiPrior hwiPrio);
#endif /* PRT_HWI_EXTERNAL_H */
+108
View File
@@ -0,0 +1,108 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: UniProton配置头文件,裁剪开关和配置项。
*/
#ifndef PRT_CONFIG_H
#define PRT_CONFIG_H
#include "prt_buildef.h"
#include "prt_typedef.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
/* ***************************** 配置系统基本信息 ******************************* */
/* 芯片主频 */
#define OS_SYS_CLOCK 0
/* ***************************** 中断模块配置 ************************** */
/* 硬中断最大支持个数 */
#define OS_HWI_MAX_NUM_CONFIG 150
/* ***************************** 配置Tick中断模块 *************************** */
/* Tick中断模块裁剪开关 */
#define OS_INCLUDE_TICK YES
/* Tick中断时间间隔,tick处理时间不能超过1/OS_TICK_PER_SECOND(s) */
#define OS_TICK_PER_SECOND 5000
/* ***************************** 配置定时器模块 ***************************** */
/* 基于TICK的软件定时器裁剪开关 */
#define OS_INCLUDE_TICK_SWTMER NO
/* 基于TICK的软件定时器最大个数 */
#define OS_TICK_SWITIMER_MAX_NUM 8
/* ***************************** 配置任务模块 ******************************* */
/* 任务模块裁剪开关 */
#define OS_INCLUDE_TASK YES
/* 最大支持的任务数,最大共支持254个 */
#define OS_TSK_MAX_SUPPORT_NUM 8
/* 缺省的任务栈大小 */
#define OS_TSK_DEFAULT_STACK_SIZE 0x800
/* IDLE任务栈的大小 */
#define OS_TSK_IDLE_STACK_SIZE 0x800
/* 任务栈初始化魔术字,默认是0xCA,只支持配置一个字节 */
#define OS_TSK_STACK_MAGIC_WORD 0xCA
/* ***************************** 配置CPU占用率及CPU告警模块 **************** */
/* CPU占用率模块裁剪开关 */
#define OS_INCLUDE_CPUP NO
/* 采样时间间隔(单位tick),若其值大于0,则作为采样周期,否则两次调用PRT_CpupNow或PRT_CpupThread间隔作为周期 */
#define OS_CPUP_SAMPLE_INTERVAL 0
/* CPU占用率告警动态配置项 */
#define OS_CONFIG_CPUP_WARN NO
/* CPU占用率告警阈值(精度为万分比) */
#define OS_CPUP_SHORT_WARN 0
/* CPU占用率告警恢复阈值(精度为万分比) */
#define OS_CPUP_SHORT_RESUME 0
/* ***************************** 配置内存管理模块 ************************** */
/* 用户可以创建的最大分区数,取值范围[0,253] */
#define OS_MEM_MAX_PT_NUM 10
/* 私有FSC内存分区起始地址 */
#define OS_MEM_FSC_PT_ADDR NULL
/* 私有FSC内存分区大小 */
#define OS_MEM_FSC_PT_SIZE 0
/* ***************************** 配置信号量管理模块 ************************* */
/* 信号量模块裁剪开关 */
#define OS_INCLUDE_SEM NO
/* 最大支持的信号量数 */
#define OS_SEM_MAX_SUPPORT_NUM 0
/* ***************************** 配置队列模块 ******************************* */
/* 队列模块裁剪开关 */
#define OS_INCLUDE_QUEUE NO
/* 最大支持的队列数,范围(0,0xFFFF] */
#define OS_QUEUE_MAX_SUPPORT_NUM 10
/* ************************* 钩子模块配置 *********************************** */
/* 硬中断进入钩子最大支持个数, 范围[0, 255] */
#define OS_HOOK_HWI_ENTRY_NUM 0
/* 硬中断退出钩子最大支持个数, 范围[0, 255] */
#define OS_HOOK_HWI_EXIT_NUM 0
/* 任务切换钩子最大支持个数, 范围[0, 255] */
#define OS_HOOK_TSK_SWITCH_NUM 0
/* IDLE钩子最大支持个数, 范围[0, 255] */
#define OS_HOOK_IDLE_NUM 0
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cpluscplus */
#endif /* __cpluscplus */
#endif /* PRT_CONFIG_H */
+311
View File
@@ -0,0 +1,311 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: UniProton的初始化C文件。
*/
#include "prt_config_internal.h"
OS_SEC_ALW_INLINE INLINE void OsConfigAddrSizeGet(uintptr_t addr, uintptr_t size,
uintptr_t *destAddr, uintptr_t *destSize)
{
*destAddr = addr;
*destSize = size;
}
U32 OsMemConfigReg(void)
{
U32 ret;
ret = OsFscMemInit(OS_MEM_FSC_PT_ADDR, OS_MEM_FSC_PT_SIZE);
if (ret != OS_OK) {
return ret;
}
return OS_OK;
}
U32 OsMemDefPtInit(void)
{
return OS_OK;
}
U32 OsMemConfigInit(void)
{
/* 系统默认FSC内存分区初始化 */
return OsMemDefPtInit();
}
U32 OsSystemReg(void)
{
struct SysModInfo sysModInfo;
sysModInfo.systemClock = OS_SYS_CLOCK;
sysModInfo.cpuType = OS_CPU_TYPE;
#if defined(OS_OPTION_HWI_MAX_NUM_CONFIG)
sysModInfo.hwiMaxNum = OS_HWI_MAX_NUM_CONFIG;
#endif
return OsSysRegister(&sysModInfo);
}
#if (OS_INCLUDE_SEM == YES)
U32 OsSemConfigReg(void)
{
struct SemModInfo semModInfo;
semModInfo.maxNum = OS_SEM_MAX_SUPPORT_NUM;
return OsSemRegister(&semModInfo);
}
#endif
#if (OS_INCLUDE_TASK == YES)
void OsTaskInfoSet(struct TskModInfo *taskModInfo)
{
taskModInfo->maxNum = OS_TSK_MAX_SUPPORT_NUM;
taskModInfo->defaultSize = OS_TSK_DEFAULT_STACK_SIZE;
taskModInfo->idleStackSize = OS_TSK_IDLE_STACK_SIZE;
taskModInfo->magicWord = WORD_PACK((U32)OS_TSK_STACK_MAGIC_WORD);
}
#else
#error "OS_INCLUDE_TASK MUST BE YES! The SWI has been cut outthe task can not cut out."
#endif
U32 OsHookConfigReg(void)
{
struct HookModInfo hookModInfo;
hookModInfo.maxNum[OS_HOOK_HWI_ENTRY] = OS_HOOK_HWI_ENTRY_NUM;
hookModInfo.maxNum[OS_HOOK_HWI_EXIT] = OS_HOOK_HWI_EXIT_NUM;
hookModInfo.maxNum[OS_HOOK_TSK_SWITCH] = OS_HOOK_TSK_SWITCH_NUM;
hookModInfo.maxNum[OS_HOOK_IDLE_PERIOD] = OS_HOOK_IDLE_NUM;
return OsHookRegister(&hookModInfo);
}
U32 OsSysConfigReg(void)
{
U32 ret;
ret = OsSystemReg();
if (ret != OS_OK) {
return ret;
}
return OS_OK;
}
#if (OS_INCLUDE_TICK == YES)
U32 OsTickConfigReg(void)
{
struct TickModInfo tickModInfo;
tickModInfo.tickPerSecond = OS_TICK_PER_SECOND;
tickModInfo.tickPriority = 0;
return OsTickRegister(&tickModInfo);
}
#endif
#if (OS_INCLUDE_TASK == YES)
U32 OsTskConfigReg(void)
{
struct TskModInfo taskModInfo;
OsTaskInfoSet(&taskModInfo);
return OsTskRegister(&taskModInfo);
}
#endif
#if (OS_INCLUDE_QUEUE == YES)
U32 OsQueueConfigReg(void)
{
return OsQueueRegister(OS_QUEUE_MAX_SUPPORT_NUM);
}
#endif
#if (OS_INCLUDE_CPUP == YES)
U32 OsCpupConfigReg(void)
{
struct CpupModInfo cpupModInfo;
cpupModInfo.cpupWarnFlag = (bool)OS_CONFIG_CPUP_WARN;
cpupModInfo.sampleTime = OS_CPUP_SAMPLE_INTERVAL;
cpupModInfo.warn = OS_CPUP_SHORT_WARN;
cpupModInfo.resume = OS_CPUP_SHORT_RESUME;
return OsCpupRegister(&cpupModInfo);
}
#endif
#if (OS_INCLUDE_TICK_SWTMER == YES)
U32 OsSwTmrConfigInit(void)
{
return OsSwTmrInit(OS_TICK_SWITIMER_MAX_NUM);
}
#endif
#if (OS_INCLUDE_CPUP == YES)
#if (OS_INCLUDE_TICK == NO)
#error "OS_INCLUDE_CPUP depend on OS_INCLUDE_TICK!"
#endif
U32 OsCpupConfigInit(void)
{
U32 ret;
ret = OsCpupInit();
if (ret != OS_OK) {
return ret;
}
if (OS_CONFIG_CPUP_WARN == YES) {
#if defined(OS_OPTION_CPUP_WARN)
OsCpupWarnInit();
#else
return OS_ERRNO_SYS_NO_CPUP_WARN;
#endif
}
return OS_OK;
}
#endif
#if (OS_INCLUDE_SEM == YES)
U32 OsSemConfigInit(void)
{
return OsSemInit();
}
#endif
#if (OS_INCLUDE_TASK == YES)
U32 OsTskConfigInit(void)
{
return OsTskInit();
}
#endif
/* 系统初始化注册表 */
struct OsModuleConfigInfo g_moduleConfigTab[] = {
/* {模块号, 模块注册函数, 模块初始化函数} */
{OS_MID_SYS, {OsSysConfigReg, NULL}},
{OS_MID_MEM, {OsMemConfigReg, OsMemConfigInit}},
{OS_MID_HWI, {NULL, OsHwiConfigInit}},
{OS_MID_HARDDRV, {NULL, PRT_HardDrvInit}},
{OS_MID_HOOK, {OsHookConfigReg, OsHookConfigInit}},
{OS_MID_EXC, {NULL, OsExcConfigInit}},
#if (OS_INCLUDE_TASK == YES)
{OS_MID_TSK, {OsTskConfigReg, OsTskConfigInit}},
#endif
#if (OS_INCLUDE_TICK == YES)
{OS_MID_TICK, {OsTickConfigReg, OsTickConfigInit}},
#endif
#if (OS_INCLUDE_TICK_SWTMER == YES)
{OS_MID_SWTMR, {NULL, OsSwTmrConfigInit}},
#endif
#if (OS_INCLUDE_CPUP == YES)
{OS_MID_CPUP, {OsCpupConfigReg, OsCpupConfigInit}},
#endif
#if (OS_INCLUDE_SEM == YES)
{OS_MID_SEM, {OsSemConfigReg, OsSemConfigInit}},
#endif
#if (OS_INCLUDE_QUEUE == YES)
{OS_MID_QUEUE, {OsQueueConfigReg, OsQueueConfigInit}},
#endif
{OS_MID_APP, {NULL, PRT_AppInit}},
{OS_MID_BUTT, {NULL, NULL}},
};
/*
* 描述:OS模块注册、初始化运行函数
*/
U32 OsModuleConfigRun(enum OsinitPhaseId initPhaseId, U32 initPhase)
{
U32 idx = 0;
U32 ret = OS_OK;
while (g_moduleConfigTab[idx].moudleId != OS_MID_BUTT) {
if (g_moduleConfigTab[idx].moudleConfigFunc[initPhaseId] == NULL) {
idx++;
continue;
}
ret = g_moduleConfigTab[idx].moudleConfigFunc[initPhaseId]();
if (ret != OS_OK) {
break;
}
idx++;
}
return ret;
}
U32 OsRegister(void)
{
return OsModuleConfigRun(OS_REGISTER_ID, OS_REGISTER_PHASE);
}
/*
* 描述:OsInitialize阶段
*/
U32 OsInitialize(void)
{
return OsModuleConfigRun(OS_INIT_ID, OS_INITIALIZE_PHASE);
}
/*
* 描述:OsStart阶段
*/
U32 OsStart(void)
{
U32 ret;
#if (OS_INCLUDE_TICK == YES)
/* 表示系统在进行启动阶段,匹配MOUDLE_ID之后,标记进入TICK模块的启动 */
ret = OsTickStart();
if (ret != OS_OK) {
return ret;
}
#endif
#if (OS_INCLUDE_TASK == YES)
/* 表示系统在进行启动阶段,匹配MOUDLE_ID之后,标记进入任务模块的启动 */
ret = OsActivate();
#else
ret = OS_OK;
#endif
return ret;
}
S32 main(void)
{
U32 ret;
OsHwInit();
/* OS模块注册 */
ret = OsRegister();
if (ret != OS_OK) {
return (S32)ret;
}
/* OS模块初始化 */
ret = OsInitialize();
if (ret != OS_OK) {
return (S32)ret;
}
/* OS启动调度 */
ret = OsStart();
if (ret != OS_OK) {
return (S32)ret;
}
/* Execution should not reach this point */
return (S32)OS_ERROR;
}
+82
View File
@@ -0,0 +1,82 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: UniProton配置私有文件。
*/
#ifndef PRT_CONFIG_INTERNAL_H
#define PRT_CONFIG_INTERNAL_H
#include <stdint.h>
#include "prt_config.h"
#include "prt_sys.h"
#include "prt_task.h"
#include "prt_sem.h"
#include "prt_tick.h"
#include "prt_exc.h"
#include "prt_cpup.h"
#include "prt_mem.h"
#include "prt_hook.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cpluscplus */
#endif /* __cpluscplus */
#define WORD_PACK(val) (((val) << 24) | ((val) << 16) | ((val) << 8) | (val))
/* UniProton模块注册函数的声明 */
extern U32 OsFscMemInit(U32 addr, U32 size);
extern U32 OsSysRegister(struct SysModInfo *modInfo);
extern U32 OsTickRegister(struct TickModInfo *modInfo);
extern U32 OsTskRegister(struct TskModInfo *modInfo);
extern U32 OsCpupRegister(struct CpupModInfo *modInfo);
extern U32 OsSemRegister(const struct SemModInfo *modInfo);
extern U32 OsHookRegister(struct HookModInfo *modInfo);
extern U32 OsHwiConfigInit(void);
extern U32 OsTickConfigInit(void);
extern U32 OsTskInit(void);
extern U32 OsCpupInit(void);
extern void OsCpupWarnInit(void);
extern U32 OsExcConfigInit(void);
extern U32 OsSemInit(void);
extern U32 OsHookConfigInit(void);
/* UniProton系统启动相关函数的声明 */
extern void OsHwInit(void);
extern U32 OsActivate(void);
extern U32 OsTickStart(void);
extern U32 PRT_HardDrvInit(void);
/* Notes: PRT_HardBootInit接口在栈保护支持随机数设置场景下必须在bss初始化后调用 */
extern void PRT_HardBootInit(void);
extern U32 PRT_AppInit(void);
extern U32 OsQueueRegister(U16 maxQueue);
extern U32 OsQueueConfigInit(void);
#if (OS_INCLUDE_TICK_SWTMER == YES)
extern U32 OsSwTmrInit(U32 maxTimerNum);
#endif
typedef U32 (*ConfigInitFunc)(void);
struct OsModuleConfigInfo {
enum MoudleId moudleId;
ConfigInitFunc moudleConfigFunc[OS_MOUDLE_CONFIG];
};
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cpluscplus */
#endif /* __cpluscplus */
#endif /* PRT_CONFIG_INTERNAL_H */
+2
View File
@@ -0,0 +1,2 @@
add_subdirectory(ipc)
add_subdirectory(kernel)
+6
View File
@@ -0,0 +1,6 @@
menu "Core Modules Configuration"
source "core/ipc/Kconfig"
source "core/kernel/Kconfig"
endmenu
+11
View File
@@ -0,0 +1,11 @@
if(${CONFIG_OS_OPTION_EVENT})
add_subdirectory(event)
endif()
if(${CONFIG_OS_OPTION_QUEUE})
add_subdirectory(queue)
endif()
add_subdirectory(sem)
+6
View File
@@ -0,0 +1,6 @@
menu "IPC Modules Configuration"
source "core/ipc/event/Kconfig"
source "core/ipc/queue/Kconfig"
source "core/ipc/sem/Kconfig"
endmenu
+1
View File
@@ -0,0 +1 @@
add_library(prt_event OBJECT prt_event.c)
+7
View File
@@ -0,0 +1,7 @@
menu "Event feature configuration"
config OS_OPTION_EVENT
bool "Whether support event module or not"
default n
endmenu
+219
View File
@@ -0,0 +1,219 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: 事件函数实现
*/
#include "prt_event.h"
#include "prt_task_external.h"
// 支持功能宏裁剪
#if defined(OS_OPTION_EVENT)
OS_SEC_L4_TEXT U32 OsEventReadParaCheck(U32 eventMask, U32 flags, U32 timeOut)
{
if (eventMask == 0) {
return OS_ERRNO_EVENT_EVENTMASK_INVALID;
}
/* 读事件模式非法或者(读事件模式为非等待模式且等待时间为0)时,返回错误 */
if (!(flags == (OS_EVENT_ALL | OS_EVENT_WAIT) || flags == (OS_EVENT_ALL | OS_EVENT_NOWAIT) ||
flags == (OS_EVENT_ANY | OS_EVENT_WAIT) || flags == (OS_EVENT_ANY | OS_EVENT_NOWAIT)) ||
(((flags & OS_EVENT_WAIT) != 0) && (timeOut == 0))) {
return OS_ERRNO_EVENT_FLAGS_INVALID;
}
return OS_OK;
}
OS_SEC_ALW_INLINE INLINE bool OsIsEventNotMatch(U32 flags, U32 event, U32 eventMask, struct TagTskCb *runTsk)
{
/* 读事件非期望获得所有事件 */
if ((flags & OS_EVENT_ALL) != 0) {
TSK_STATUS_SET(runTsk, OS_TSK_EVENT_TYPE);
if ((eventMask != (event & eventMask))) {
return TRUE;
}
} else {
TSK_STATUS_CLEAR(runTsk, OS_TSK_EVENT_TYPE);
if ((event & eventMask) == 0) {
return TRUE;
}
}
return FALSE;
}
OS_SEC_ALW_INLINE INLINE void OsEventTimeOutSet(U32 timeOut, struct TagTskCb *runTsk)
{
if (timeOut == OS_EVENT_WAIT_FOREVER) {
TSK_STATUS_CLEAR(runTsk, OS_TSK_TIMEOUT);
} else {
TSK_STATUS_SET(runTsk, OS_TSK_TIMEOUT);
OsTskTimerAdd(runTsk, timeOut);
}
}
OS_SEC_ALW_INLINE INLINE U32 OsEventReadNeedSche(U32 flags, struct TagTskCb *runTsk,
U32 timeOut, U32 *event)
{
/* 读事件处于等待读取模式 */
if ((flags & OS_EVENT_NOWAIT) != 0) {
return OS_ERRNO_EVENT_READ_FAILED;
}
/* 如果锁任务的情况下 */
if (OS_TASK_LOCK_DATA != 0) {
return OS_ERRNO_EVENT_READ_IN_LOCK;
}
OsTskReadyDel(runTsk);
TSK_STATUS_SET(runTsk, OS_TSK_EVENT_PEND);
OsEventTimeOutSet(timeOut, runTsk);
OsTskSchedule();
/* 判断是否超时返回并做超时处理 */
if ((runTsk->taskStatus & OS_TSK_TIMEOUT) != 0) {
TSK_STATUS_CLEAR(runTsk, OS_TSK_TIMEOUT);
return OS_ERRNO_EVENT_READ_TIMEOUT;
}
*event = runTsk->event;
return OS_OK;
}
/*
* 描述:读事件操作
*/
OS_SEC_L4_TEXT U32 PRT_EventRead(U32 eventMask, U32 flags, U32 timeOut, U32 *events)
{
U32 ret;
U32 event;
uintptr_t intSave;
struct TagTskCb *runTsk = NULL;
bool needSchedule = FALSE;
ret = OsEventReadParaCheck(eventMask, flags, timeOut);
if (ret != OS_OK) {
return ret;
}
intSave = OsIntLock();
if (OS_INT_ACTIVE) {
OsIntRestore(intSave);
return OS_ERRNO_EVENT_READ_NOT_IN_TASK;
}
runTsk = RUNNING_TASK;
runTsk->eventMask = eventMask;
event = runTsk->event;
needSchedule = OsIsEventNotMatch(flags, event, eventMask, runTsk);
/* 期望的事件一件都没有发生,或者在OS_EVENT_ALL情况下没有发生期望所有事件 */
if (needSchedule == TRUE) {
ret = OsEventReadNeedSche(flags, runTsk, timeOut, &event);
if (ret != OS_OK) {
OsIntRestore(intSave);
return ret;
}
}
/* 清除已经读取到的事件 */
runTsk->event &= (~eventMask);
if (events != NULL) {
*events = event & eventMask;
}
OsIntRestore(intSave);
return OS_OK;
}
OS_SEC_ALW_INLINE INLINE void OsEventStateChange(U32 taskStatus, struct TagTskCb *taskCb)
{
if ((taskStatus & OS_TSK_TIMEOUT) != 0) {
/*
* 添加PEND状态时,会加上TIMEOUT标志和timer,或者都不加。
* 所以此时有TIMEOUT标志就一定有timer,且只有一个,且只用于该PEND方式
*/
OS_TSK_DELAY_LOCKED_DETACH(taskCb);
TSK_STATUS_CLEAR(taskCb, OS_TSK_TIMEOUT);
}
if ((OS_TSK_SUSPEND & taskStatus) == 0) {
OsTskReadyAddBgd(taskCb);
}
}
/*
* 描述:写事件操作
*/
OS_SEC_L4_TEXT U32 PRT_EventWrite(U32 taskId, U32 events)
{
struct TagTskCb *taskCb = NULL;
uintptr_t intSave;
bool needSchedule = FALSE;
U32 eventMask;
U32 taskStatus;
if (CHECK_TSK_PID_OVERFLOW(taskId)) {
return OS_ERRNO_EVENT_TASKID_INVALID;
}
if (events == 0) {
return OS_ERRNO_EVENT_INVALID;
}
intSave = OsIntLock();
taskCb = (struct TagTskCb *)GET_TCB_HANDLE(taskId);
taskStatus = taskCb->taskStatus;
if (TSK_IS_UNUSED(taskCb)) {
OsIntRestore(intSave);
return OS_ERRNO_EVENT_TSK_NOT_CREATED;
}
taskCb->event |= events;
/* 判断目的线程是否阻塞于读事件 */
if ((taskStatus & OS_TSK_EVENT_PEND) != 0) {
eventMask = taskCb->eventMask;
/* 判断是否需要任务调度 */
if ((taskStatus & OS_TSK_EVENT_TYPE) != 0) {
if (eventMask == (taskCb->event & eventMask)) {
needSchedule = TRUE;
}
} else {
if ((taskCb->event & eventMask) != 0) {
needSchedule = TRUE;
}
}
if (needSchedule) {
TSK_STATUS_CLEAR(taskCb, OS_TSK_EVENT_PEND);
OsEventStateChange(taskStatus, taskCb);
OsTskSchedule();
OsIntRestore(intSave);
return OS_OK;
}
}
OsIntRestore(intSave);
return OS_OK;
}
#endif
+79
View File
@@ -0,0 +1,79 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: 队列模块内部头文件。
*/
#ifndef PRT_QUEUE_EXTERNAL_H
#define PRT_QUEUE_EXTERNAL_H
#include "prt_queue.h"
#include "prt_list_external.h"
#include "prt_cpu_external.h"
/* 模块间宏定义 */
#define OS_QUEUE_NODE_HEAD_LEN (sizeof(struct QueNode) - 2)
/* 队列状态 */
#define OS_QUEUE_UNUSED 0 /* 队列没有使用 */
#define OS_QUEUE_USED 1 /* 已经被使用 */
#define OS_QUEUE_PID_INVALID 0xFFFFU /* 节点未使用 */
#define OS_QUEUE_NODE_SIZE_ALIGN 0x2U
#define GET_QUEUE_HANDLE(queueId) (((struct TagQueCb *)g_allQueue) + (queueId))
#define OS_QUEUE_INNER_ID(queueId) ((queueId) - 1)
#define OS_QUEUE_ID(innerId) ((innerId) + 1)
#define OS_QUEUE_NAME_LEN 16
/* 队列控制块结构体 */
struct TagQueCb {
/* 队列起始地址指针 */
U8 *queue;
/* 队列状态 */
U16 queueState;
/* 队列长度(队列节点个数) */
U16 nodeNum;
/* 每个节点长度,单位word */
U16 nodeSize;
/* 当前队列头下标 */
U16 queueHead;
/* 当前队列尾下标 */
U16 queueTail;
/* 队列节点使用的峰值 */
U16 nodePeak;
/* 队列写资源计数器 */
U16 writableCnt;
/* 队列读资源计数器 */
U16 readableCnt;
/* 写队列超时LIST */
struct TagListObject writeList;
/* 读队列超时LIST */
struct TagListObject readList;
};
/* 队列节点的数据结构 */
struct QueNode {
/* 源PID */
U16 srcPid;
/* 节点长度 */
U16 size;
/* buf是初始化申请的,长度>=1 */
U8 buf[2];
};
/* 队列最大个数 */
extern U16 g_maxQueue;
extern struct TagQueCb *g_allQueue;
#endif /* PRT_QUEUE_EXTERNAL_H */
+54
View File
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: 信号量模块内部头文件
*/
#ifndef PRT_SEM_EXTERNAL_H
#define PRT_SEM_EXTERNAL_H
#include "prt_sem.h"
#include "prt_task_external.h"
#define OS_SEM_UNUSED 0
#define OS_SEM_USED 1
#define OS_SEM_WITH_LOCK_FLAG 1
#define OS_SEM_WITHOUT_LOCK_FLAG 0
#define GET_SEM_LIST(ptr) LIST_COMPONENT(ptr, struct TagSemCb, semList)
#define GET_SEM(semid) (((struct TagSemCb *)g_allSem) + (semid))
#define GET_SEM_TSK(semid) (((SEM_TSK_S *)g_semTsk) + (semid))
#define GET_TSK_SEM(tskid) (((TSK_SEM_S *)g_tskSem) + (tskid))
struct TagSemCb {
/* 是否使用 OS_SEM_UNUSED/OS_SEM_USED */
U16 semStat;
/* 核内信号量索引号 */
U16 semId;
/* 当该信号量已用时,其信号量计数 */
U32 semCount;
/* 挂接阻塞于该信号量的任务 */
struct TagListObject semList;
U32 maxSemCount;
/* Pend到该信号量的线程ID */
U32 semOwner;
/* 信号量唤醒阻塞任务的方式 */
enum SemMode semMode;
};
/* 模块间全局变量声明 */
extern U16 g_maxSem;
/* 指向核内信号量控制块 */
extern struct TagSemCb *g_allSem;
#endif /* PRT_SEM_EXTERNAL_H */
+4
View File
@@ -0,0 +1,4 @@
add_library(prt_queue OBJECT prt_queue.c)
add_library(prt_queue_del OBJECT prt_queue_del.c)
add_library(prt_queue_minor OBJECT prt_queue_minor.c)
add_library(prt_queue_init OBJECT prt_queue_init.c)
+4
View File
@@ -0,0 +1,4 @@
config OS_OPTION_QUEUE
bool "Whether support normal queue module or not"
default n
+308
View File
@@ -0,0 +1,308 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: 队列函数实现
*/
#include "prt_queue_external.h"
#include "prt_task_external.h"
#include "prt_asm_cpu_external.h"
OS_SEC_ALW_INLINE INLINE U32 OsGetSrcPid(void)
{
U32 srcPid;
if (OS_HWI_ACTIVE) {
/* 硬中断创建消息不具体区别中断号 */
srcPid = COMPOSE_PID(OsGetHwThreadId(), OS_HWI_HANDLE);
} else {
srcPid = RUNNING_TASK->taskPid;
}
return srcPid;
}
/*
* 描述:内部Pend操作,这个函数在调用之前必须关中断。
*/
OS_SEC_ALW_INLINE INLINE U32 OsInnerPend(U16 *count, struct TagListObject *pendList, U32 timeOut)
{
struct TagTskCb *runTsk = NULL;
/* 判断是否需要阻塞 */
if (*count > 0) {
(*count)--;
return OS_OK;
}
/* 阻塞任务 */
if (timeOut == OS_QUEUE_NO_WAIT) {
return OS_ERRNO_QUEUE_NO_SOURCE;
}
if (OS_INT_ACTIVE) {
return OS_ERRNO_QUEUE_IN_INTERRUPT;
}
/* 如果锁任务的情况下 */
if (OS_TASK_LOCK_DATA != 0) {
return OS_ERRNO_QUEUE_PEND_IN_LOCK;
}
/* 利用局部变量 runTsk 完成对任务控制块的相关操作,不修改 RUNNING_TASK */
runTsk = (struct TagTskCb *)RUNNING_TASK;
/* 从任务的Ready list上把当前任务删除,添加到pend list上 */
OsTskReadyDel(runTsk);
TSK_STATUS_SET(runTsk, OS_TSK_QUEUE_PEND);
ListTailAdd(&runTsk->pendList, pendList);
/* 如果timeOut > 0,timeOut为等待时间,如果timeOut == OS_QUEUE_WAIT_FOREVER,表示永久等待 */
if (timeOut != OS_QUEUE_WAIT_FOREVER) {
/* 如果不是永久等待则将任务挂到计时器链表中,设置OS_TSK_TIMEOUT是为了判断是否等待超时 */
TSK_STATUS_SET(runTsk, OS_TSK_TIMEOUT);
OsTskTimerAdd(runTsk, timeOut);
}
/* 调用函数之前已经关中断,此处关中断进行调度 */
/* 触发任务调度 */
OsTskSchedule();
TSK_STATUS_CLEAR(runTsk, OS_TSK_QUEUE_BUSY);
/* 判断是否是等待队列超时 */
if ((runTsk->taskStatus & OS_TSK_TIMEOUT) != 0) {
TSK_STATUS_CLEAR(runTsk, OS_TSK_TIMEOUT);
/* 在函数的外面会开中断 */
return OS_ERRNO_QUEUE_TIMEOUT;
}
/* 在函数的外面会开中断 */
return OS_OK;
}
OS_SEC_ALW_INLINE INLINE bool OsQueuePendNeedProc(struct TagListObject *objectList)
{
struct TagTskCb *resumedTask = NULL;
/* 判断是否有任务阻塞于该队列 */
if (ListEmpty(objectList)) {
return FALSE;
}
/* 激活阻塞在该队列的首个任务 */
resumedTask = GET_TCB_PEND(OS_LIST_FIRST(objectList));
ListDelete(OS_LIST_FIRST(objectList));
/* 去除该任务的队列阻塞位 */
TSK_STATUS_CLEAR(resumedTask, OS_TSK_QUEUE_PEND);
/* 如果阻塞的任务属于定时等待的任务时候,去掉其定时等待标志位,并将其从去除 */
if ((resumedTask->taskStatus & OS_TSK_TIMEOUT) != 0) {
/*
* 添加PEND状态时,会加上TIMEOUT标志和timer,或者都不加。
* 所以此时有TIMEOUT标志就一定有timer,且只有一个,且只用于该PEND方式
*/
OS_TSK_DELAY_LOCKED_DETACH(resumedTask);
TSK_STATUS_CLEAR(resumedTask, OS_TSK_TIMEOUT);
}
TSK_STATUS_SET(resumedTask, OS_TSK_QUEUE_BUSY);
/* 如果去除队列阻塞位后,该任务不处于挂起态则将该任务挂入就绪队列并触发任务调度 */
if ((resumedTask->taskStatus & OS_TSK_SUSPEND) == 0) {
OsTskReadyAddBgd(resumedTask);
}
return TRUE;
}
/*
* 描述:读指定队列
*/
OS_SEC_L4_TEXT U32 PRT_QueueRead(U32 queueId, void *bufferAddr, U32 *len, U32 timeOut)
{
uintptr_t intSave;
U32 ret;
U32 bufLen;
U32 innerId = OS_QUEUE_INNER_ID(queueId);
struct TagQueCb *queueCb = NULL;
struct QueNode *queueNode = NULL;
if (innerId >= g_maxQueue) {
return OS_ERRNO_QUEUE_INVALID;
}
if ((bufferAddr == NULL) || (len == NULL)) {
return OS_ERRNO_QUEUE_PTR_NULL;
}
if (*len == 0) {
return OS_ERRNO_QUEUE_SIZE_ZERO;
}
bufLen = *len;
/* 获取指定队列控制块 */
queueCb = (struct TagQueCb *)GET_QUEUE_HANDLE(innerId);
intSave = OsIntLock();
if (queueCb->queueState == OS_QUEUE_UNUSED) {
ret = OS_ERRNO_QUEUE_NOT_CREATE;
goto QUEUE_END;
}
/* 读队列PEND */
ret = OsInnerPend(&queueCb->readableCnt, &queueCb->readList, timeOut);
if (ret != OS_OK) {
goto QUEUE_END;
}
/* 获取该队列中第一个有数据结点首地址,并将数据存入buffer中 */
queueNode = (struct QueNode *)(uintptr_t)&queueCb->queue[(queueCb->queueHead) * (queueCb->nodeSize)];
/* 如果buf的长度小于数据长度,则仅返回buf大小的数据,如果大于,则返回全部数据 */
if (*len > queueNode->size) {
*len = queueNode->size;
}
if (memcpy_s(bufferAddr, bufLen, (void *)queueNode->buf, *len) != EOK) {
OS_GOTO_SYS_ERROR1();
}
queueNode->srcPid = OS_QUEUE_PID_INVALID;
/* 队列头指针加1 */
queueCb->queueHead++;
/* 如果队列头指针已经到队列尾,那么头指针指向队列头 */
if (queueCb->queueHead == queueCb->nodeNum) {
queueCb->queueHead = 0;
}
if (OsQueuePendNeedProc(&queueCb->writeList)) {
OsTskSchedule();
OsIntRestore(intSave);
return OS_OK;
}
queueCb->writableCnt++;
QUEUE_END:
OsIntRestore(intSave);
return ret;
}
OS_SEC_L4_TEXT U32 OsQueueWriteParaCheck(U32 innerId, uintptr_t bufferAddr, U32 bufferSize, U32 prio)
{
if (innerId >= g_maxQueue) {
return OS_ERRNO_QUEUE_INVALID;
}
if (bufferAddr == 0) {
return OS_ERRNO_QUEUE_PTR_NULL;
}
if (bufferSize == 0) {
return OS_ERRNO_QUEUE_SIZE_ZERO;
}
if (prio > (U32)OS_QUEUE_URGENT) {
return OS_ERRNO_QUEUE_PRIO_INVALID;
}
return OS_OK;
}
OS_SEC_ALW_INLINE INLINE void OsQueueCpData2Node(U32 prio, uintptr_t bufferAddr, U32 bufferSize,
struct TagQueCb *queueCb)
{
U16 peak;
struct QueNode *queueNode = NULL;
if (prio == (U32)OS_QUEUE_NORMAL) {
/* 普通消息加到队列尾部 */
queueNode = (struct QueNode *)(uintptr_t)&queueCb->queue[((queueCb->queueTail) * (queueCb->nodeSize))];
queueCb->queueTail++;
if (queueCb->queueTail == queueCb->nodeNum) {
queueCb->queueTail = 0;
}
} else {
/* 紧急消息加到队列头上 */
if (queueCb->queueHead == 0) {
queueCb->queueHead = queueCb->nodeNum;
}
queueCb->queueHead--;
queueNode = (struct QueNode *)(uintptr_t)&queueCb->queue[((queueCb->queueHead) * (queueCb->nodeSize))];
}
if (memcpy_s((void *)queueNode->buf, (queueCb->nodeSize - OS_QUEUE_NODE_HEAD_LEN),
(void *)bufferAddr, bufferSize) != EOK) {
OS_GOTO_SYS_ERROR1();
}
queueNode->size = (U16)bufferSize;
queueNode->srcPid = (U16)OsGetSrcPid();
peak = queueCb->queueTail > queueCb->queueHead ? queueCb->queueTail - queueCb->queueHead
: (queueCb->nodeNum - queueCb->queueHead) + queueCb->queueTail;
if (peak > queueCb->nodePeak) {
queueCb->nodePeak = peak;
}
}
/*
* 描述:写指定队列
*/
OS_SEC_L4_TEXT U32 PRT_QueueWrite(U32 queueId, void *bufferAddr, U32 bufferSize, U32 timeOut, U32 prio)
{
U32 ret;
uintptr_t intSave;
U32 innerId = OS_QUEUE_INNER_ID(queueId);
struct TagQueCb *queueCb = NULL;
ret = OsQueueWriteParaCheck(innerId, (uintptr_t)bufferAddr, bufferSize, prio);
if (ret != OS_OK) {
return ret;
}
/* 获取指定队列控制块 */
queueCb = (struct TagQueCb *)GET_QUEUE_HANDLE(innerId);
intSave = OsIntLock();
if (queueCb->queueState == OS_QUEUE_UNUSED) {
ret = OS_ERRNO_QUEUE_NOT_CREATE;
goto QUEUE_END;
}
if (bufferSize > (queueCb->nodeSize - OS_QUEUE_NODE_HEAD_LEN)) {
ret = OS_ERRNO_QUEUE_SIZE_TOO_BIG;
goto QUEUE_END;
}
/* 读队列PEND */
ret = OsInnerPend(&queueCb->writableCnt, &queueCb->writeList, timeOut);
if (ret != OS_OK) {
goto QUEUE_END;
}
/* 选取消息节点,初始化消息节点拷贝数据 */
OsQueueCpData2Node(prio, (uintptr_t)bufferAddr, bufferSize, queueCb);
if (OsQueuePendNeedProc(&queueCb->readList)) {
OsTskSchedule();
OsIntRestore(intSave);
return OS_OK;
}
queueCb->readableCnt++;
QUEUE_END:
OsIntRestore(intSave);
return ret;
}
+60
View File
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: 队列函数实现
*/
#include "prt_mem.h"
#include "prt_queue_external.h"
/*
* 描述:删除队列,只提给供实验室使用
*/
OS_SEC_L4_TEXT U32 PRT_QueueDelete(U32 queueId)
{
uintptr_t intSave;
U32 ret;
U32 innerId = OS_QUEUE_INNER_ID(queueId);
struct TagQueCb *queueCb = NULL;
if (innerId >= g_maxQueue) {
return OS_ERRNO_QUEUE_INVALID;
}
/* 获取指定队列控制块 */
queueCb = (struct TagQueCb *)GET_QUEUE_HANDLE(innerId);
intSave = OsIntLock();
if (queueCb->queueState == OS_QUEUE_UNUSED) {
ret = OS_ERRNO_QUEUE_NOT_CREATE;
goto QUEUE_END;
}
if (!ListEmpty(&queueCb->writeList) || !ListEmpty(&queueCb->readList)) {
ret = OS_ERRNO_QUEUE_IN_TSKUSE;
goto QUEUE_END;
}
if ((queueCb->writableCnt + queueCb->readableCnt) != queueCb->nodeNum) {
ret = OS_ERRNO_QUEUE_BUSY;
goto QUEUE_END;
}
ret = PRT_MemFree((U32)OS_MID_QUEUE, (void *)(queueCb->queue));
if (ret != OS_OK) {
goto QUEUE_END;
}
queueCb->queueState = OS_QUEUE_UNUSED;
QUEUE_END:
OsIntRestore(intSave);
return ret;
}
+148
View File
@@ -0,0 +1,148 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: 队列初始化函数实现
*/
#include "securec.h"
#include "prt_queue_external.h"
#include "prt_mem_external.h"
#include "prt_lib_external.h"
/* 队列最大个数 */
OS_SEC_BSS U16 g_maxQueue;
OS_SEC_BSS struct TagQueCb *g_allQueue;
/*
* 描述:队列注册
*/
OS_SEC_L4_TEXT U32 OsQueueRegister(U16 maxQueue)
{
if (maxQueue == 0) {
return OS_ERRNO_QUEUE_MAXNUM_ZERO;
}
g_maxQueue = maxQueue;
return OS_OK;
}
OS_SEC_L4_TEXT U32 OsQueueConfigInit(void)
{
void *addr = NULL;
addr = OsMemAlloc(OS_MID_QUEUE, OS_MEM_DEFAULT_FSC_PT, g_maxQueue * sizeof(struct TagQueCb));
if (addr == NULL) {
return OS_ERRNO_QUEUE_NO_MEMORY;
}
if (memset_s(addr, g_maxQueue * sizeof(struct TagQueCb), 0, g_maxQueue * sizeof(struct TagQueCb)) != EOK) {
OS_GOTO_SYS_ERROR1();
}
g_allQueue = (struct TagQueCb *)addr;
return OS_OK;
}
OS_SEC_ALW_INLINE INLINE U32 OsQueueGetNodeSize(U16 nodeSize)
{
return ALIGN(nodeSize, OS_QUEUE_NODE_SIZE_ALIGN) + OS_QUEUE_NODE_HEAD_LEN;
}
OS_SEC_L4_TEXT U32 OsQueueCreatParaCheck(U16 nodeNum, U16 nodeSize, const U32 *queueId)
{
if (queueId == NULL) {
return OS_ERRNO_QUEUE_CREAT_PTR_NULL;
}
if ((nodeNum == 0) || (nodeSize == 0)) {
return OS_ERRNO_QUEUE_PARA_ZERO;
}
if (OsQueueGetNodeSize(nodeSize) > OS_MAX_U16) {
return OS_ERRNO_QUEUE_NSIZE_INVALID;
}
return OS_OK;
}
OS_SEC_L4_TEXT U32 OsQueueCreate(U16 nodeNum, U16 maxNodeSize, U32 *queueId)
{
U32 index;
U32 qId = 0;
struct QueNode *queueNode = NULL;
U16 nodeSize = maxNodeSize;
struct TagQueCb *queueCb = NULL;
/* 获取一个空闲的队列资源 */
queueCb = g_allQueue;
for (index = 0; index < g_maxQueue; index++, queueCb++) {
if (queueCb->queueState == OS_QUEUE_UNUSED) {
qId = OS_QUEUE_ID(index);
break;
}
}
if (index == g_maxQueue) {
return OS_ERRNO_QUEUE_CB_UNAVAILABLE;
}
nodeSize = (U16)OsQueueGetNodeSize(nodeSize);
queueCb->queue = (U8 *)OsMemAlloc(OS_MID_QUEUE, OS_MEM_DEFAULT_FSC_PT, (U32)nodeNum * (U32)nodeSize);
if (queueCb->queue == NULL) {
return OS_ERRNO_QUEUE_CREATE_NO_MEMORY;
}
for (index = 0; index < nodeNum; index++) {
queueNode = (struct QueNode *)(uintptr_t)&queueCb->queue[index * nodeSize];
queueNode->srcPid = OS_QUEUE_PID_INVALID;
}
queueCb->nodeNum = nodeNum;
queueCb->nodeSize = nodeSize;
queueCb->queueState = OS_QUEUE_USED;
INIT_LIST_OBJECT(&queueCb->writeList);
INIT_LIST_OBJECT(&queueCb->readList);
queueCb->writableCnt = nodeNum;
queueCb->queueHead = 0;
queueCb->queueTail = 0;
queueCb->nodePeak = 0;
queueCb->readableCnt = 0;
*queueId = qId;
return OS_OK;
}
/*
* 描述:创建队列接口
*/
OS_SEC_L4_TEXT U32 PRT_QueueCreate(U16 nodeNum, U16 maxNodeSize, U32 *queueId)
{
uintptr_t intSave;
U32 ret;
U32 qId = 0;
ret = OsQueueCreatParaCheck(nodeNum, maxNodeSize, queueId);
if (ret != OS_OK) {
return ret;
}
intSave = OsIntLock();
ret = OsQueueCreate(nodeNum, maxNodeSize, &qId);
if (ret != OS_OK) {
OsIntRestore(intSave);
return ret;
}
*queueId = qId;
OsIntRestore(intSave);
return OS_OK;
}
+96
View File
@@ -0,0 +1,96 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: 队列维测函数实现
*/
#include "prt_queue_external.h"
OS_SEC_L2_TEXT U32 OsQueueGetParaCheck(U32 innerId, const U32 *num, struct TagQueCb **queueCb)
{
if (innerId >= g_maxQueue) {
return OS_ERRNO_QUEUE_INVALID;
}
if (num == NULL) {
return OS_ERRNO_QUEUE_PTR_NULL;
}
*queueCb = (struct TagQueCb *)GET_QUEUE_HANDLE(innerId);
if ((*queueCb)->queueState == OS_QUEUE_UNUSED) {
return OS_ERRNO_QUEUE_NOT_CREATE;
}
return OS_OK;
}
/*
* 描述:获取消息队列的历史最大使用长度。
*/
OS_SEC_L2_TEXT U32 PRT_QueueGetUsedPeak(U32 queueId, U32 *queueUsedNum)
{
U32 innerId = OS_QUEUE_INNER_ID(queueId);
struct TagQueCb *queueCb = NULL;
uintptr_t intSave;
U32 ret;
intSave = OsIntLock();
ret = OsQueueGetParaCheck(innerId, queueUsedNum, &queueCb);
if (ret != OS_OK) {
OsIntRestore(intSave);
return ret;
}
*queueUsedNum = (U32)queueCb->nodePeak;
OsIntRestore(intSave);
return OS_OK;
}
/*
* 描述:获取当前等待消息队列中指定源任务的待处理消息个数。
*/
OS_SEC_L2_TEXT U32 PRT_QueueGetNodeNum(U32 queueId, U32 taskPid, U32 *queueNum)
{
U32 ret;
U32 loop;
uintptr_t intSave;
U32 num = 0;
U32 numAll = 0;
U32 innerId = OS_QUEUE_INNER_ID(queueId);
struct TagQueCb *queueCb = NULL;
struct QueNode *queueNode = NULL;
intSave = OsIntLock();
ret = OsQueueGetParaCheck(innerId, queueNum, &queueCb);
if (ret != OS_OK) {
OsIntRestore(intSave);
return ret;
}
if (taskPid != OS_QUEUE_PID_INVALID) {
for (loop = 0; loop < queueCb->nodeNum; loop++) {
queueNode = (struct QueNode *)(uintptr_t)&queueCb->queue[loop * (queueCb->nodeSize)];
if (queueNode->srcPid == taskPid) {
num++;
}
if (queueNode->srcPid != OS_QUEUE_PID_INVALID) {
numAll++;
}
}
}
*queueNum = (taskPid == OS_QUEUE_PID_ALL) ? numAll : num;
OsIntRestore(intSave);
return OS_OK;
}
+3
View File
@@ -0,0 +1,3 @@
add_library(prt_sem OBJECT prt_sem.c)
add_library(prt_sem_init OBJECT prt_sem_init.c)
add_library(prt_sem_minor OBJECT prt_sem_minor.c)
+2
View File
@@ -0,0 +1,2 @@
menu "Semaphore feature configuration"
endmenu
+226
View File
@@ -0,0 +1,226 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: 信号量模块
*/
#include "prt_sem_external.h"
#include "prt_asm_cpu_external.h"
/* 核内信号量最大个数 */
OS_SEC_BSS U16 g_maxSem;
/*
* 描述:把当前运行任务挂接到信号量链表上
*/
OS_SEC_L0_TEXT void OsSemPendListPut(struct TagSemCb *semPended, U32 timeOut)
{
struct TagTskCb *curTskCb = NULL;
struct TagTskCb *runTsk = RUNNING_TASK;
struct TagListObject *pendObj = &runTsk->pendList;
OsTskReadyDel((struct TagTskCb *)runTsk);
runTsk->taskSem = (void *)semPended;
TSK_STATUS_SET(runTsk, OS_TSK_PEND);
/* 根据唤醒方式挂接此链表,同优先级再按FIFO子顺序插入 */
if (semPended->semMode == SEM_MODE_PRIOR) {
LIST_FOR_EACH(curTskCb, &semPended->semList, struct TagTskCb, pendList) {
if (curTskCb->priority > runTsk->priority) {
ListTailAdd(pendObj, &curTskCb->pendList);
goto TIMER_ADD;
}
}
}
/* 如果到这里,说明是FIFO方式;或者是优先级方式且挂接首个节点或者挂接尾节点 */
ListTailAdd(pendObj, &semPended->semList);
TIMER_ADD:
// timer超时链表添加
if (timeOut != OS_WAIT_FOREVER) {
/* 如果不是永久等待则将任务挂到计时器链表中,设置OS_TSK_TIMEOUT是为了判断是否等待超时 */
OsTskTimerAdd((struct TagTskCb *)runTsk, timeOut);
TSK_STATUS_SET(runTsk, OS_TSK_TIMEOUT);
}
}
/*
* 描述:从非空信号量链表上摘首个任务放入到ready队列
*/
OS_SEC_L0_TEXT struct TagTskCb *OsSemPendListGet(struct TagSemCb *semPended)
{
struct TagTskCb *taskCb = GET_TCB_PEND(LIST_FIRST(&(semPended->semList)));
ListDelete(LIST_FIRST(&(semPended->semList)));
/* 如果阻塞的任务属于定时等待的任务时候,去掉其定时等待标志位,并将其从去除 */
if (TSK_STATUS_TST(taskCb, OS_TSK_TIMEOUT)) {
OS_TSK_DELAY_LOCKED_DETACH(taskCb);
}
// 必须先去除 OS_TSK_TIMEOUT 态,再入队[睡眠时是先出ready队,再置OS_TSK_TIMEOUT态]
TSK_STATUS_CLEAR(taskCb, OS_TSK_TIMEOUT | OS_TSK_PEND);
taskCb->taskSem = NULL;
/* 如果去除信号量阻塞位后,该任务不处于阻塞态则将该任务挂入就绪队列并触发任务调度 */
if (!TSK_STATUS_TST(taskCb, OS_TSK_SUSPEND)) {
OsTskReadyAddBgd(taskCb);
}
return taskCb;
}
OS_SEC_L0_TEXT U32 OsSemPendParaCheck(U32 timeout)
{
if (timeout == 0) {
return OS_ERRNO_SEM_UNAVAILABLE;
}
/* 如果锁任务的情况下 */
if (OS_TASK_LOCK_DATA != 0) {
return OS_ERRNO_SEM_PEND_IN_LOCK;
}
return OS_OK;
}
OS_SEC_L0_TEXT bool OsSemPendNotNeedSche(struct TagSemCb *semPended, struct TagTskCb *runTsk)
{
// 信号量获取成功
if (semPended->semCount > 0) {
semPended->semCount--;
semPended->semOwner = runTsk->taskPid;
return TRUE;
}
return FALSE;
}
/*
* 描述:指定信号量的P操作
*/
OS_SEC_L0_TEXT U32 PRT_SemPend(SemHandle semHandle, U32 timeout)
{
uintptr_t intSave;
U32 ret;
struct TagTskCb *runTsk = NULL;
struct TagSemCb *semPended = NULL;
if (semHandle >= (SemHandle)g_maxSem) {
return OS_ERRNO_SEM_INVALID;
}
semPended = GET_SEM(semHandle);
intSave = OsIntLock();
if (semPended->semStat == OS_SEM_UNUSED) {
OsIntRestore(intSave);
return OS_ERRNO_SEM_INVALID;
}
/* 如果是中断的情况 */
if (OS_INT_ACTIVE) {
OsIntRestore(intSave);
return OS_ERRNO_SEM_PEND_INTERR;
}
runTsk = (struct TagTskCb *)RUNNING_TASK;
if (OsSemPendNotNeedSche(semPended, runTsk) == TRUE) {
OsIntRestore(intSave);
return OS_OK;
}
ret = OsSemPendParaCheck(timeout);
if (ret != OS_OK) {
OsIntRestore(intSave);
return ret;
}
/* 把当前任务挂接在信号量链表上 */
OsSemPendListPut(semPended, timeout);
if (timeout != OS_WAIT_FOREVER) {
/* 触发任务调度 */
OsTskSchedule();
/* 判断是否是等待信号量超时 */
if (TSK_STATUS_TST(runTsk, OS_TSK_TIMEOUT)) {
TSK_STATUS_CLEAR(runTsk, OS_TSK_TIMEOUT);
OsIntRestore(intSave);
return OS_ERRNO_SEM_TIMEOUT;
}
} else {
/* 恢复ps的快速切换 */
OsTskScheduleFastPs(intSave);
}
OsIntRestore(intSave);
return OS_OK;
}
OS_SEC_ALW_INLINE INLINE void OsSemPostSchePre(struct TagSemCb *semPosted)
{
struct TagTskCb *resumedTask = NULL;
resumedTask = OsSemPendListGet(semPosted);
semPosted->semOwner = resumedTask->taskPid;
}
OS_SEC_ALW_INLINE INLINE U32 OsSemPostErrorCheck(struct TagSemCb *semPosted, SemHandle semHandle)
{
(void)semHandle;
/* 检查信号量控制块是否UNUSED,排除大部分错误场景 */
if (semPosted->semStat == OS_SEM_UNUSED) {
return OS_ERRNO_SEM_INVALID;
}
/* post计数型信号量的错误场景, 释放计数型信号量且信号量计数大于最大计数 */
if ((semPosted)->maxSemCount <= (semPosted)->semCount) {
return OS_ERRNO_SEM_OVERFLOW;
}
/* post同步二进制信号量或者不存在上述错误场景 */
return OS_OK;
}
/*
* 描述:指定信号量的V操作
*/
OS_SEC_L0_TEXT U32 PRT_SemPost(SemHandle semHandle)
{
U32 ret;
uintptr_t intSave;
struct TagSemCb *semPosted = NULL;
if (semHandle >= (SemHandle)g_maxSem) {
return OS_ERRNO_SEM_INVALID;
}
semPosted = GET_SEM(semHandle);
intSave = OsIntLock();
/* 检查post信号量时的错误场景 */
ret = OsSemPostErrorCheck(semPosted, semHandle);
if (ret != OS_OK) {
OsIntRestore(intSave);
return ret;
}
/* 如果有任务阻塞在信号量上,就激活信号量阻塞队列上的首个任务 */
if (!ListEmpty(&semPosted->semList)) {
OsSemPostSchePre(semPosted);
/* 相当于快速切换+中断恢复 */
OsTskScheduleFastPs(intSave);
} else {
/* 释放信号量,把持有信号量的任务ID设置为OS_THREAD_ID_INVALID */
semPosted->semCount++;
semPosted->semOwner = OS_INVALID_OWNER_ID;
}
OsIntRestore(intSave);
return OS_OK;
}
+147
View File
@@ -0,0 +1,147 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: 信号量模块
*/
#include "prt_sem_external.h"
OS_SEC_BSS struct TagListObject g_unusedSemList;
OS_SEC_BSS struct TagSemCb *g_allSem;
OS_SEC_L4_TEXT U32 OsSemRegister(const struct SemModInfo *modInfo)
{
if (modInfo->maxNum == 0) {
return OS_ERRNO_SEM_REG_ERROR;
}
g_maxSem = modInfo->maxNum;
return OS_OK;
}
/*
* 描述:信号量初始化
*/
OS_SEC_L4_TEXT U32 OsSemInit(void)
{
struct TagSemCb *semNode = NULL;
U32 idx;
U32 ret = OS_OK;
/* g_maxSem在注册时已判断是否大于0,这里不需判断 */
g_allSem = (struct TagSemCb *)OsMemAllocAlign((U32)OS_MID_SEM,
OS_MEM_DEFAULT_FSC_PT,
g_maxSem * sizeof(struct TagSemCb),
MEM_ADDR_ALIGN_004);
if (g_allSem == NULL) {
return OS_ERRNO_SEM_NO_MEMORY;
}
if (memset_s((void *)g_allSem, g_maxSem * sizeof(struct TagSemCb), 0, g_maxSem * sizeof(struct TagSemCb)) !=
EOK) {
OS_GOTO_SYS_ERROR1();
}
INIT_LIST_OBJECT(&g_unusedSemList);
for (idx = 0; idx < g_maxSem; idx++) {
semNode = ((struct TagSemCb *)g_allSem) + idx;
semNode->semId = (U16)idx;
ListTailAdd(&semNode->semList, &g_unusedSemList);
}
return ret;
}
/*
* 描述:创建一个信号量
*/
OS_SEC_L4_TEXT U32 OsSemCreate(U32 count, enum SemMode semMode, SemHandle *semHandle, U32 cookie)
{
uintptr_t intSave;
struct TagSemCb *semCreated = NULL;
struct TagListObject *unusedSem = NULL;
(void)cookie;
if (semHandle == NULL) {
return OS_ERRNO_SEM_PTR_NULL;
}
intSave = OsIntLock();
if (ListEmpty(&g_unusedSemList)) {
OsIntRestore(intSave);
return OS_ERRNO_SEM_ALL_BUSY;
}
/* 在空闲链表中取走一个控制节点 */
unusedSem = OS_LIST_FIRST(&(g_unusedSemList));
ListDelete(unusedSem);
/* 获取到空闲节点对应的信号量控制块,并开始填充控制块 */
semCreated = (GET_SEM_LIST(unusedSem));
semCreated->semCount = count;
semCreated->semStat = OS_SEM_USED;
semCreated->semMode = semMode;
semCreated->semOwner = OS_INVALID_OWNER_ID;
semCreated->maxSemCount = OS_SEM_COUNT_MAX;
INIT_LIST_OBJECT(&semCreated->semList);
*semHandle = (SemHandle)semCreated->semId;
OsIntRestore(intSave);
return OS_OK;
}
/*
* 描述:创建一个信号量
*/
OS_SEC_L4_TEXT U32 PRT_SemCreate(U32 count, SemHandle *semHandle)
{
U32 ret;
if (count > OS_SEM_COUNT_MAX) {
return OS_ERRNO_SEM_OVERFLOW;
}
ret = OsSemCreate(count, SEM_MODE_FIFO, semHandle, (U32)(uintptr_t)semHandle);
return ret;
}
/*
* 描述:删除一个信号量
*/
OS_SEC_L4_TEXT U32 PRT_SemDelete(SemHandle semHandle)
{
uintptr_t intSave;
struct TagSemCb *semDeleted = NULL;
if (semHandle >= (SemHandle)g_maxSem) {
return OS_ERRNO_SEM_INVALID;
}
semDeleted = GET_SEM(semHandle);
intSave = OsIntLock();
if (semDeleted->semStat == OS_SEM_UNUSED) {
OsIntRestore(intSave);
return OS_ERRNO_SEM_INVALID;
}
if (!ListEmpty(&semDeleted->semList)) {
OsIntRestore(intSave);
return OS_ERRNO_SEM_PENDED;
}
semDeleted->semStat = OS_SEM_UNUSED;
ListAdd(&semDeleted->semList, &g_unusedSemList);
OsIntRestore(intSave);
return OS_OK;
}
+116
View File
@@ -0,0 +1,116 @@
/*
* Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
*
* UniProton is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* Create: 2009-12-22
* Description: 信号量模块
*/
#include "prt_sem_external.h"
/*
* 描述:获取信号量详细信息。
*/
OS_SEC_L4_TEXT U32 PRT_SemGetInfo(SemHandle semHandle, struct SemInfo *semInfo)
{
struct TagSemCb *semGet = NULL;
uintptr_t intSave;
if (semInfo == NULL) {
return OS_ERRNO_SEM_INFO_NULL;
}
if (semHandle >= (SemHandle)g_maxSem) {
return OS_ERRNO_SEM_INVALID;
}
semGet = GET_SEM(semHandle);
intSave = OsIntLock();
if (semGet->semStat == OS_SEM_UNUSED) {
OsIntRestore(intSave);
return OS_ERRNO_SEM_INVALID;
}
semInfo->owner = semGet->semOwner;
semInfo->count = semGet->semCount;
semInfo->mode = semGet->semMode;
semInfo->type = SEM_TYPE_COUNT;
OsIntRestore(intSave);
return OS_OK;
}
/*
* 描述:获取指定信号量的计数
*/
OS_SEC_L4_TEXT U32 PRT_SemGetCount(SemHandle semHandle, U32 *semCnt)
{
U32 ret;
struct SemInfo semInfo = {0};
if (semCnt == NULL) {
return OS_ERRNO_SEM_COUNT_GET_PTR_NULL;
}
ret = PRT_SemGetInfo(semHandle, &semInfo);
if (ret == OS_OK) {
*semCnt = semInfo.count;
}
return ret;
}
/*
* 描述:获取阻塞在指定核内信号量的任务PID清单
*/
OS_SEC_L4_TEXT U32 PRT_SemGetPendList(SemHandle semHandle, U32 *tskCnt, U32 *pidBuf, U32 bufLen)
{
uintptr_t intSave;
U32 taskCount = 0;
U32 len = (bufLen / sizeof(U32));
struct TagTskCb *tskCb = NULL;
struct TagSemCb *semCb = NULL;
if (tskCnt == NULL) {
return OS_ERRNO_SEM_INPUT_ERROR;
}
*tskCnt = 0;
if ((pidBuf == NULL) || (len == 0)) {
return OS_ERRNO_SEM_INPUT_ERROR;
}
if (semHandle >= (SemHandle)g_maxSem) {
return OS_ERRNO_SEM_INVALID;
}
semCb = GET_SEM(semHandle);
intSave = OsIntLock();
if (semCb->semStat == OS_SEM_UNUSED) {
OsIntRestore(intSave);
return OS_ERRNO_SEM_INVALID;
}
LIST_FOR_EACH(tskCb, &semCb->semList, struct TagTskCb, pendList) {
if (taskCount < len) {
pidBuf[taskCount] = tskCb->taskPid;
}
taskCount++;
}
*tskCnt = taskCount;
OsIntRestore(intSave);
if (taskCount > len) {
return OS_ERRNO_SEM_INPUT_BUF_NOT_ENOUGH;
}
return OS_OK;
}
+6
View File
@@ -0,0 +1,6 @@
add_subdirectory(irq)
add_subdirectory(kexc)
add_subdirectory(sys)
add_subdirectory(task)
add_subdirectory(tick)
add_subdirectory(timer)

Some files were not shown because too many files have changed in this diff Show More