Compare commits
231 Commits
OpenHarmon
...
OpenHarmon
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
887a845874 | ||
|
|
8ee33a771b | ||
|
|
c182540a92 | ||
|
|
d837ed3e9d | ||
|
|
a2371f1b27 | ||
|
|
8245cd5cd0 | ||
|
|
b9311b9aa0 | ||
|
|
8cf75d80fd | ||
|
|
4491d561c7 | ||
|
|
1bf61bb4b0 | ||
|
|
b62463abc5 | ||
|
|
6ffea886d3 | ||
|
|
9de6f57cda | ||
|
|
307ab396a5 | ||
|
|
96b2eaeab6 | ||
|
|
58e67dde3b | ||
|
|
f74067b24f | ||
|
|
86bc68744d | ||
|
|
39db69b6bf | ||
|
|
87c6e9476d | ||
|
|
94537e17ae | ||
|
|
9717eafff7 | ||
|
|
0712c2df56 | ||
|
|
50b4e91f91 | ||
|
|
443d9deb9b | ||
|
|
caa28225a8 | ||
|
|
fdb12dbe31 | ||
|
|
8ebfe352f5 | ||
|
|
2332f34a79 | ||
|
|
314af71a48 | ||
|
|
2ef5ff366e | ||
|
|
5acd9b36ff | ||
|
|
314102c234 | ||
|
|
b31437fe27 | ||
|
|
a2852d8bce | ||
|
|
0ce46a3989 | ||
|
|
b5db6ee2d4 | ||
|
|
f0ed09be65 | ||
|
|
802e01de21 | ||
|
|
d95a1523f2 | ||
|
|
0a1df72f7e | ||
|
|
48484444ce | ||
|
|
6240af2522 | ||
|
|
b1b46451e7 | ||
|
|
54936c19bd | ||
|
|
7a6242549f | ||
|
|
07ef35ccdf | ||
|
|
08e3025ec5 | ||
|
|
ae2c3c5823 | ||
|
|
d32fea7096 | ||
|
|
915e5b9517 | ||
|
|
6e665e6771 | ||
|
|
a338ba8f69 | ||
|
|
81d02b4fea | ||
|
|
bd607c8922 | ||
|
|
f23481e041 | ||
|
|
792b131d55 | ||
|
|
3969fbfac8 | ||
|
|
33e2b5e085 | ||
|
|
79099bb28c | ||
|
|
11e8e895d3 | ||
|
|
a562b67f90 | ||
|
|
fafd3b66d4 | ||
|
|
5e3a29dd97 | ||
|
|
d1d19e088d | ||
|
|
2c85b0ec6d | ||
|
|
773613af16 | ||
|
|
0f0e4dfafd | ||
|
|
2a5a515f50 | ||
|
|
215a1f6dc0 | ||
|
|
093af869d5 | ||
|
|
ef8d27db07 | ||
|
|
b22234dd6a | ||
|
|
5169a23adf | ||
|
|
bc42e348d0 | ||
|
|
93cc5747a2 | ||
|
|
96b4c460e2 | ||
|
|
23f634bde5 | ||
|
|
aee17ecfa6 | ||
|
|
9b160141c4 | ||
|
|
3141961013 | ||
|
|
51a6c21315 | ||
|
|
c5a9ba4abf | ||
|
|
7fa979c67c | ||
|
|
b5e84d5516 | ||
|
|
c277e8d543 | ||
|
|
230a2f348f | ||
|
|
92e3844061 | ||
|
|
088a6d5bbd | ||
|
|
d4d6489fb9 | ||
|
|
c1b2b15a87 | ||
|
|
1d9a5820f2 | ||
|
|
4443b74ea6 | ||
|
|
6e1bdfe1de | ||
|
|
3798091d87 | ||
|
|
459cabf7de | ||
|
|
475db62db1 | ||
|
|
d46c69ee78 | ||
|
|
047203b7fb | ||
|
|
61cbf83f5d | ||
|
|
53117f9f47 | ||
|
|
75f975c424 | ||
|
|
c4dc5ab0f8 | ||
|
|
c8015dcb49 | ||
|
|
7719bb28e5 | ||
|
|
84a180d585 | ||
|
|
deff7c921f | ||
|
|
e4e3caccf2 | ||
|
|
19aa1bb5bc | ||
|
|
9996ef80d6 | ||
|
|
f63c45930c | ||
|
|
5a9d53b644 | ||
|
|
be03374c3c | ||
|
|
4e11ded476 | ||
|
|
8023547244 | ||
|
|
013a953926 | ||
|
|
97c4a5813f | ||
|
|
ada151d89b | ||
|
|
0facb0c017 | ||
|
|
7ad3a22b4d | ||
|
|
0a87c04d58 | ||
|
|
ee3403deaf | ||
|
|
02beb6b04d | ||
|
|
509cf59bef | ||
|
|
2868891bc8 | ||
|
|
67d74559d1 | ||
|
|
251a597bb4 | ||
|
|
5d53c84812 | ||
|
|
af5bc32e38 | ||
|
|
c1614ce2b4 | ||
|
|
93f029b430 | ||
|
|
fa0b8b0dcb | ||
|
|
d75383400e | ||
|
|
669f619040 | ||
|
|
9709d29b87 | ||
|
|
11bca47b6e | ||
|
|
2118c84616 | ||
|
|
7fe9cc9aa0 | ||
|
|
299813cdb4 | ||
|
|
870cf67c51 | ||
|
|
f64457162c | ||
|
|
c8064436dd | ||
|
|
218d16f85f | ||
|
|
8dea15c4fc | ||
|
|
56dfd80ea5 | ||
|
|
cea551e99e | ||
|
|
b195b40bf2 | ||
|
|
1a56599021 | ||
|
|
c1a6245368 | ||
|
|
8692ed33a3 | ||
|
|
ff7da435cf | ||
|
|
12fed74722 | ||
|
|
4fd6a663ac | ||
|
|
23d56f4b2a | ||
|
|
8f5cefe41a | ||
|
|
1d33f5e4b0 | ||
|
|
cb5f862eaf | ||
|
|
3027311003 | ||
|
|
3b37750f37 | ||
|
|
c136cfdf97 | ||
|
|
56c93a641b | ||
|
|
285d90979b | ||
|
|
3ad5942301 | ||
|
|
7bd5a806e9 | ||
|
|
911a767992 | ||
|
|
15a2c17f79 | ||
|
|
704cca97b1 | ||
|
|
6b732ca351 | ||
|
|
71c76e8b08 | ||
|
|
70f3aa1c11 | ||
|
|
c24c38b084 | ||
|
|
403d6dc428 | ||
|
|
d3fb23cca0 | ||
|
|
b3841ed1dd | ||
|
|
10f683da91 | ||
|
|
ae05de3ffd | ||
|
|
d5e46ad863 | ||
|
|
ad8e96a00f | ||
|
|
b3481b1fa1 | ||
|
|
c842251bab | ||
|
|
ba27241b02 | ||
|
|
0526c14017 | ||
|
|
fd2227e5c8 | ||
|
|
39efd6fb30 | ||
|
|
f2466c4165 | ||
|
|
ad15bbd6a4 | ||
|
|
bbce405227 | ||
|
|
c7b91d7a31 | ||
|
|
97283b7c5d | ||
|
|
97b5b0837b | ||
|
|
73a99977de | ||
|
|
3c48951857 | ||
|
|
453f91d09c | ||
|
|
948501ac73 | ||
|
|
1ab9813256 | ||
|
|
6d7c9dfe59 | ||
|
|
bf045e3eba | ||
|
|
d8c8c22666 | ||
|
|
cda85bf1b0 | ||
|
|
37ef8ca7ae | ||
|
|
2e621bc323 | ||
|
|
ceaed2dc86 | ||
|
|
aa6385ce16 | ||
|
|
76dc343c88 | ||
|
|
77338f4c2b | ||
|
|
e5179be5b5 | ||
|
|
452f36403d | ||
|
|
2dd6c080da | ||
|
|
c56f5bc7bd | ||
|
|
d469da29c6 | ||
|
|
7fcf7ee3e6 | ||
|
|
8515f0dc8f | ||
|
|
66f242f85b | ||
|
|
80f02595d7 | ||
|
|
75f61870a0 | ||
|
|
82fad6c36f | ||
|
|
59225cb6df | ||
|
|
bfa25fcaa3 | ||
|
|
586d9a18b3 | ||
|
|
b458e12ed5 | ||
|
|
eca03e5ed6 | ||
|
|
2e92427d8f | ||
|
|
ef4bdf6d10 | ||
|
|
8649b14591 | ||
|
|
b0119f6185 | ||
|
|
b55cfc1ba7 | ||
|
|
e5e9289a08 | ||
|
|
1f4b7aa85d | ||
|
|
86d5544a3f | ||
|
|
d0efdfc20d | ||
|
|
558ce14bec |
56
BUILD.gn
56
BUILD.gn
@@ -27,14 +27,25 @@
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
declare_args() {
|
||||
enable_ohos_kernel_liteos_m_cppsupport = true
|
||||
enable_ohos_kernel_liteos_m_cpup = true
|
||||
enable_ohos_kernel_liteos_m_exchook = true
|
||||
enable_ohos_kernel_liteos_m_kal = true
|
||||
enable_ohos_kernel_liteos_m_fs = true
|
||||
enable_ohos_kernel_liteos_m_backtrace = true
|
||||
enable_ohos_kernel_liteos_m_test = false
|
||||
import("config.gni")
|
||||
|
||||
LITEOS_LOS_CONFIG_H = rebase_path("$LITEOSTOPDIR/kernel/include/los_config.h")
|
||||
|
||||
config("los_config") {
|
||||
cflags = [ "-Werror" ]
|
||||
|
||||
asmflags = [
|
||||
"-DCLZ=CLZ",
|
||||
"-imacros",
|
||||
"$LITEOS_LOS_CONFIG_H",
|
||||
]
|
||||
|
||||
include_dirs = [
|
||||
"//kernel/liteos_m/kernel/include",
|
||||
"//kernel/liteos_m/kernel/arch/include",
|
||||
"//kernel/liteos_m/utils",
|
||||
"//third_party/bounds_checking_function/include",
|
||||
]
|
||||
}
|
||||
|
||||
group("kernel") {
|
||||
@@ -43,25 +54,40 @@ group("kernel") {
|
||||
"utils:utils",
|
||||
"//third_party/bounds_checking_function:libsec_static",
|
||||
]
|
||||
if (enable_ohos_kernel_liteos_m_cppsupport == true) {
|
||||
if (enable_ohos_kernel_liteos_m_cppsupport) {
|
||||
deps += [ "components/cppsupport:cppsupport" ]
|
||||
}
|
||||
if (enable_ohos_kernel_liteos_m_cpup == true) {
|
||||
if (enable_ohos_kernel_liteos_m_cpup) {
|
||||
deps += [ "components/cpup:cpup" ]
|
||||
}
|
||||
if (enable_ohos_kernel_liteos_m_exchook == true) {
|
||||
if (enable_ohos_kernel_liteos_m_exchook) {
|
||||
deps += [ "components/exchook:exchook" ]
|
||||
}
|
||||
if (enable_ohos_kernel_liteos_m_backtrace == true) {
|
||||
if (enable_ohos_kernel_liteos_m_backtrace) {
|
||||
deps += [ "components/backtrace:backtrace" ]
|
||||
}
|
||||
if (enable_ohos_kernel_liteos_m_fs == true) {
|
||||
if (enable_ohos_kernel_liteos_m_fs) {
|
||||
deps += [ "components/fs:fs" ]
|
||||
}
|
||||
if (enable_ohos_kernel_liteos_m_kal == true) {
|
||||
if (enable_ohos_kernel_liteos_m_pm) {
|
||||
deps += [ "components/power:pm" ]
|
||||
}
|
||||
if (enable_ohos_kernel_liteos_m_trace) {
|
||||
deps += [ "components/trace:trace" ]
|
||||
}
|
||||
if (enable_ohos_kernel_liteos_m_kal) {
|
||||
deps += [ "kal:kal" ]
|
||||
}
|
||||
if (enable_ohos_kernel_liteos_m_test == true) {
|
||||
if (enable_ohos_kernel_liteos_m_shell) {
|
||||
deps += [ "components/shell:shell" ]
|
||||
}
|
||||
if (enable_ohos_kernel_liteos_m_test) {
|
||||
deps += [ "testsuits:test" ]
|
||||
}
|
||||
if (enable_ohos_kernel_liteos_m_lwip) {
|
||||
deps += [ ohos_kernel_liteos_m_lwip_path ]
|
||||
}
|
||||
if (enable_ohos_kernel_liteos_m_dynlink) {
|
||||
deps += [ "components/dynlink:dynlink" ]
|
||||
}
|
||||
}
|
||||
|
||||
86
OAT.xml
Normal file
86
OAT.xml
Normal file
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
This is the configuration file template for OpenHarmony OSS Audit Tool, please copy it to your project root dir and modify it refer to OpenHarmony/tools_oat/README.
|
||||
|
||||
-->
|
||||
|
||||
<configuration>
|
||||
<oatconfig>
|
||||
<licensefile></licensefile>
|
||||
<policylist>
|
||||
<policy name="projectPolicy" desc="">
|
||||
<policyitem type="copyright" name="Huawei Technologies Co., Ltd. All rights reserved." path=".*" desc="original liteos copyright"/>
|
||||
<policyitem type="license" name="BSD-3-Clause" path=".*" desc="Liteos kernel use bsd3 license"/>
|
||||
<policyitem type="license" name="BSD-3-Clause" path=".*" desc="Liteos kernel use bsd3 license"/>
|
||||
</policy>
|
||||
</policylist>
|
||||
<filefilterlist>
|
||||
<filefilter name="defaultFilter" desc="文件属于FreeBSD仓库软连接,本仓库屏蔽告警,在FreeBSD仓库进行处理">
|
||||
<filteritem type="filepath" name="kernel/arch/risc-v/nuclei/gcc/nmsis/Library/.*" desc="文件属于三方芯片的二进制代码,属于社区贡献,不用提供额外的说明"/>
|
||||
<filteritem type="filepath" name="targets/riscv_nuclei_demo_soc_gcc/.*" desc="文件属于nuclei三方芯片的源代码,文件头说明跟随liteos_m/LICENSE,不用额外说明"/>
|
||||
<filteritem type="filepath" name="targets/riscv_nuclei_gd32vf103_soc_gcc/.*" desc="文件属于nuclei三方芯片的源代码,文件头说明跟随liteos_m/LICENSE,不用额外说明"/>
|
||||
<filteritem type="filepath" name="NOTICE" desc="NOTICE文件"/>
|
||||
<filteritem type="filepath" name="kernel/arch/risc-v/nuclei" desc="该文件的license为apache 2.0符合"/>
|
||||
</filefilter>
|
||||
<filefilter name="defaultFilter" desc="Files not to check">
|
||||
<!--filteritem type="filename" name="*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
|
||||
<!--filteritem type="filepath" name="abcdefg/.*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
|
||||
<!--filteritem type="filepath" name="projectroot/[a-zA-Z0-9]{20,}.sh" desc="Temp files"/-->
|
||||
</filefilter>
|
||||
<filefilter name="defaultPolicyFilter" desc="Filters for compatibility,license header policies">
|
||||
<!--filteritem type="filename" name="*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
|
||||
<!--filteritem type="filepath" name="abcdefg/.*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
|
||||
<!--filteritem type="filepath" name="projectroot/[a-zA-Z0-9]{20,}.sh" desc="Temp files"/-->
|
||||
</filefilter>
|
||||
<filefilter name="copyrightPolicyFilter" desc="Filters for copyright header policies">
|
||||
<!--filteritem type="filename" name="*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
|
||||
<!--filteritem type="filepath" name="abcdefg/.*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
|
||||
<!--filteritem type="filepath" name="projectroot/[a-zA-Z0-9]{20,}.sh" desc="Temp files"/-->
|
||||
</filefilter>
|
||||
<filefilter name="licenseFileNamePolicyFilter" desc="Filters for LICENSE file policies">
|
||||
<!--filteritem type="filename" name="*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
|
||||
<!--filteritem type="filepath" name="abcdefg/.*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
|
||||
<!--filteritem type="filepath" name="projectroot/[a-zA-Z0-9]{20,}.sh" desc="Temp files"/-->
|
||||
</filefilter>
|
||||
<filefilter name="readmeFileNamePolicyFilter" desc="Filters for README file policies">
|
||||
<!--filteritem type="filename" name="*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
|
||||
<!--filteritem type="filepath" name="abcdefg/.*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
|
||||
<!--filteritem type="filepath" name="projectroot/[a-zA-Z0-9]{20,}.sh" desc="Temp files"/-->
|
||||
</filefilter>
|
||||
<filefilter name="readmeOpenSourcefileNamePolicyFilter" desc="Filters for README.OpenSource file policies">
|
||||
<!--filteritem type="filename" name="*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
|
||||
<!--filteritem type="filepath" name="abcdefg/.*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
|
||||
<!--filteritem type="filepath" name="projectroot/[a-zA-Z0-9]{20,}.sh" desc="Temp files"/-->
|
||||
</filefilter>
|
||||
<filefilter name="binaryFileTypePolicyFilter" desc="Filters for binary file policies">
|
||||
<!--filteritem type="filename" name="*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
|
||||
<!--filteritem type="filepath" name="abcdefg/.*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
|
||||
<!--filteritem type="filepath" name="projectroot/[a-zA-Z0-9]{20,}.sh" desc="Temp files"/-->
|
||||
</filefilter>
|
||||
|
||||
</filefilterlist>
|
||||
<licensematcherlist>
|
||||
<!--licensematcher name="uvwxyz License" desc="If the scanning result is InvalidLicense, you can define matching rules here. Note that quotation marks must be escaped.">
|
||||
<licensetext name="
|
||||
uvwxyz license textA xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
" desc=""/>
|
||||
<licensetext name="
|
||||
uvwxyz license textB xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
" desc=""/>
|
||||
</licensematcher-->
|
||||
</licensematcherlist>
|
||||
</oatconfig>
|
||||
</configuration>
|
||||
12
README.md
12
README.md
@@ -23,6 +23,7 @@ The directory structure is listed as below, for the detailed directories, please
|
||||
│ ├── backtrace # Backtrace support
|
||||
│ ├── cppsupport # C++ support
|
||||
│ ├── cpup # CPU possession (CPUP)
|
||||
│ ├── dynlink # Dynamic loader & linker
|
||||
│ ├── exchook # Exception hook
|
||||
│ ├── fs # File system
|
||||
│ └── net # Network support
|
||||
@@ -68,18 +69,9 @@ make clean; make
|
||||
|
||||
After the compilation is successful, the executable file **NUCLEO-F767.hex** is generated in the **cortex-m7\_nucleo\_f767zi\_gcc/build** directory. Burn the file to the corresponding board using STM32 ST-LINK Utility.
|
||||
|
||||
## Change Log
|
||||
|
||||
v1.0.1
|
||||
1. removed these KAL apis: `KalThreadGetInfo`,`KalDelayUs`,`KalTimerCreate`,`KalTimerStart`,`KalTimerChange`,`KalTimerStop`,`KalTimerDelete`,`KalTimerIsRunning`,`KalTickToMs`,`KalMsToTick`,`KalGetMemInfo`
|
||||
2. add some POSIX apis
|
||||
|
||||
v1.0
|
||||
1. first release
|
||||
|
||||
## Repositories Involved<a name="section1371113476307"></a>
|
||||
|
||||
[Kernel subsystem](https://gitee.com/openharmony/docs/blob/master/en/readme/kernel.md)
|
||||
[Kernel subsystem](https://gitee.com/openharmony/docs/blob/HEAD/en/readme/kernel.md)
|
||||
|
||||
**kernel\_liteos\_m**
|
||||
|
||||
|
||||
20
README_zh.md
20
README_zh.md
@@ -23,6 +23,7 @@ OpenHarmony LiteOS-M内核是面向IoT领域构建的轻量级物联网操作系
|
||||
│ ├── backtrace # 回溯栈支持
|
||||
│ ├── cppsupport # C++支持
|
||||
│ ├── cpup # CPUP功能
|
||||
│ ├── dynlink # 动态加载与链接
|
||||
│ ├── exchook # 异常钩子
|
||||
│ ├── fs # 文件系统
|
||||
│ └── net # Network功能
|
||||
@@ -47,15 +48,15 @@ OpenHarmony LiteOS-M内核是面向IoT领域构建的轻量级物联网操作系
|
||||
|
||||
## 使用说明<a name="section3732185231214"></a>
|
||||
|
||||
OpenHarmony LiteOS-M内核的编译构建系统是一个基于gn和ninja的组件化构建系统,支持按组件配置、裁剪和拼装,按需构建出定制化的产品。编译构建系统的详细信息可以参考[轻量和小型系统编译构建指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/subsystems/%E8%BD%BB%E9%87%8F%E5%92%8C%E5%B0%8F%E5%9E%8B%E7%B3%BB%E7%BB%9F%E7%BC%96%E8%AF%91%E6%9E%84%E5%BB%BA%E6%8C%87%E5%AF%BC.md)。本文主要介绍如何基于gn和ninja编译LiteOS-M工程,GCC+Makefile、IAR、Keil MDK等编译方式可以参考社区爱好者贡献的站点。
|
||||
OpenHarmony LiteOS-M内核的编译构建系统是一个基于gn和ninja的组件化构建系统,支持按组件配置、裁剪和拼装,按需构建出定制化的产品。本文主要介绍如何基于gn和ninja编译LiteOS-M工程,GCC+Makefile、IAR、Keil MDK等编译方式可以参考社区爱好者贡献的站点。
|
||||
|
||||
### 搭建系统基础环境
|
||||
|
||||
在搭建各个开发板环境前,需要完成OpenHarmony系统基础环境搭建。系统基础环境主要是指OpenHarmony的编译环境和开发环境,详细介绍请参考官方站点[Ubuntu编译环境准备](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/Ubuntu%E7%BC%96%E8%AF%91%E7%8E%AF%E5%A2%83%E5%87%86%E5%A4%87.md)。开发者需要根据环境搭建文档,完成下述软件的安装:Python3.7+、gn、ninja、hb。对于LiteOS-M内核,还需要安装Make构建工具和[ARM GCC编译工具链](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads)。
|
||||
在搭建各个开发板环境前,需要完成OpenHarmony系统基础环境搭建。系统基础环境主要是指OpenHarmony的编译环境和开发环境,详细介绍请参考官方站点[Ubuntu编译环境准备](https://gitee.com/openharmony/docs/blob/HEAD/zh-cn/device-dev/quick-start/quickstart-lite-env-setup-linux.md)。开发者需要根据环境搭建文档,完成下述软件的安装:Python3.7+、gn、ninja、hb。对于LiteOS-M内核,还需要安装Make构建工具和[ARM GCC编译工具链](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads)。
|
||||
|
||||
### 获取OpenHarmony源码
|
||||
|
||||
开发者需要在Linux服务器上通过Git克隆获取OpenHarmony最新源码,详细的源码获取方式,请见[源码获取](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/%E6%BA%90%E7%A0%81%E8%8E%B7%E5%8F%96.md)。获取OpenHarmony完整仓代码后,假设克隆目录为`~/openHarmony`。
|
||||
开发者需要在Linux服务器上通过Git克隆获取OpenHarmony最新源码,详细的源码获取方式,请见[源码获取](https://gitee.com/openharmony/docs/blob/HEAD/zh-cn/device-dev/get-code/sourcecode-acquire.md)。获取OpenHarmony完整仓代码后,假设克隆目录为`~/openHarmony`。
|
||||
|
||||
### 获取示例工程源码
|
||||
|
||||
@@ -77,7 +78,7 @@ chmod +x ~/openHarmony/device/st/nucleo_f767zi/build.sh
|
||||
cp -r ~/nucleo_f767zi/vendor/st ~/openHarmony/vendor/st
|
||||
```
|
||||
|
||||
关于示例代码目录的说明,可以参考资料站点[板级目录规范](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/porting/%E7%A7%BB%E6%A4%8D%E6%A6%82%E8%BF%B0-0.md#section6204129143013)。如果需要自行移植开发板,请参考[板级系统移植](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/porting/%E6%9D%BF%E7%BA%A7%E7%B3%BB%E7%BB%9F%E7%A7%BB%E6%A4%8D.md)。
|
||||
关于示例代码目录的说明,可以参考资料站点[板级目录规范](https://gitee.com/openharmony/docs/blob/HEAD/zh-cn/device-dev/porting/transplant-chip-board-overview.md)。如果需要自行移植开发板,请参考[板级系统移植](https://gitee.com/openharmony/docs/blob/HEAD/zh-cn/device-dev/porting/transplant-chip-board.md)。
|
||||
|
||||
### 编译运行
|
||||
|
||||
@@ -118,18 +119,9 @@ LiteOS-M内核移植的具体开发板的工程由社区开发者提供,可以
|
||||
|
||||
该仓包含OpenHarmony LiteOS-M内核移植支持`Nucleo-F767ZI`开发板的工程代码,支持Ninja、GCC、IAR等方式进行编译。
|
||||
|
||||
## 修改日志
|
||||
|
||||
v1.0.1
|
||||
1. 删除以下KAL接口: `KalThreadGetInfo`,`KalDelayUs`,`KalTimerCreate`,`KalTimerStart`,`KalTimerChange`,`KalTimerStop`,`KalTimerDelete`,`KalTimerIsRunning`,`KalTickToMs`,`KalMsToTick`,`KalGetMemInfo`
|
||||
2. 添加部分POSIX接口
|
||||
|
||||
v1.0
|
||||
1. 首次发布
|
||||
|
||||
## 相关仓<a name="section1371113476307"></a>
|
||||
|
||||
[内核子系统](https://gitee.com/openharmony/docs/blob/master/zh-cn/readme/%E5%86%85%E6%A0%B8%E5%AD%90%E7%B3%BB%E7%BB%9F.md)
|
||||
[内核子系统](https://gitee.com/openharmony/docs/blob/HEAD/zh-cn/readme/%E5%86%85%E6%A0%B8%E5%AD%90%E7%B3%BB%E7%BB%9F.md)
|
||||
|
||||
**kernel\_liteos\_m**
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
│ ├── backtrace --- Backtrace
|
||||
│ ├── cppsupport --- C++
|
||||
│ ├── cpup --- CPUP
|
||||
│ ├── dynlink --- Dynamic loader & linker
|
||||
│ ├── exchook --- Exception hook
|
||||
│ ├── fs --- File System
|
||||
│ └── net --- Network
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
│ ├── backtrace --- 回溯栈支持
|
||||
│ ├── cppsupport --- C++支持
|
||||
│ ├── cpup --- CPUP功能
|
||||
│ ├── dynlink --- 动态加载与链接
|
||||
│ ├── exchook --- 异常钩子
|
||||
│ ├── fs --- 文件系统
|
||||
│ └── net --- 网络功能
|
||||
|
||||
59
bundle.json
Normal file
59
bundle.json
Normal file
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"name": "@ohos/kernel_liteos_m",
|
||||
"version": "",
|
||||
"description": "liteos-m内核",
|
||||
"homePage": "https://gitee.com/openharmony",
|
||||
"license": "BSD 3-clause",
|
||||
"repository": "https://gitee.com/openharmony/kernel_liteos_m",
|
||||
"domain": "os",
|
||||
"language": "",
|
||||
"publishAs": "code-segment",
|
||||
"private": false,
|
||||
"scripts": {},
|
||||
"tags": [
|
||||
"kernel"
|
||||
],
|
||||
"keywords": [
|
||||
"kernel",
|
||||
"liteos-m"
|
||||
],
|
||||
"envs": [],
|
||||
"dirs": [],
|
||||
"author": {
|
||||
"name": "",
|
||||
"email": "",
|
||||
"url": ""
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "",
|
||||
"email": "",
|
||||
"url": ""
|
||||
}
|
||||
],
|
||||
"segment": {
|
||||
"destPath": "kernel/liteos_m"
|
||||
},
|
||||
"component": {
|
||||
"name": "liteos-m",
|
||||
"subsystem": "liteos_m",
|
||||
"syscap": [
|
||||
"SystemCapability.Kernel.liteos-m"
|
||||
],
|
||||
"features": [],
|
||||
"adapted_system_type": [
|
||||
"mini"
|
||||
],
|
||||
"rom": "",
|
||||
"ram": "",
|
||||
"deps": {
|
||||
"components": [],
|
||||
"third_party": []
|
||||
},
|
||||
"build": {
|
||||
"sub_component": [],
|
||||
"inner_kits": [],
|
||||
"test": []
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,13 +27,10 @@
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import("//kernel/liteos_m/config.gni")
|
||||
|
||||
static_library("backtrace") {
|
||||
sources = [ "los_backtrace.c" ]
|
||||
|
||||
include_dirs = [
|
||||
"../../kernel/include",
|
||||
"../../kernel/arch/include",
|
||||
"../../utils",
|
||||
"//third_party/bounds_checking_function/include",
|
||||
]
|
||||
configs += [ "$LITEOSTOPDIR:los_config" ]
|
||||
}
|
||||
|
||||
@@ -33,8 +33,19 @@
|
||||
#include "los_task.h"
|
||||
#include "los_debug.h"
|
||||
|
||||
|
||||
#if (LOSCFG_BACKTRACE_TYPE != 0)
|
||||
/* This function is used to judge whether the data in the stack is a code section address.
|
||||
The default code section is only one, but there may be more than one. Modify the
|
||||
judgment condition to support multiple code sections. */
|
||||
WEAK BOOL OsStackDataIsCodeAddr(UINTPTR value)
|
||||
{
|
||||
if ((value >= CODE_START_ADDR) && (value < CODE_END_ADDR)) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
#if (LOSCFG_BACKTRACE_TYPE == 1)
|
||||
#define OS_BACKTRACE_START 2
|
||||
/* Thumb instruction, so the pc must be an odd number */
|
||||
@@ -140,7 +151,7 @@ STATIC INLINE UINT32 OsStackAddrGet(UINTPTR *stackStart, UINTPTR *stackEnd, UINT
|
||||
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
|
||||
*stackEnd = (UINTPTR)taskCB->topOfStack + taskCB->stackSize;
|
||||
if ((*stackStart < (UINTPTR)taskCB->topOfStack) || (*stackStart >= *stackEnd)) {
|
||||
PRINT_ERR("psp stack [0x%x, 0x%x], cur sp(0x%x) is overflow, cur task id is %d!\n",
|
||||
PRINT_ERR("psp stack [0x%x, 0x%x], cur sp(0x%x) is overflow, cur task id is %u!\n",
|
||||
taskCB->topOfStack, *stackEnd, *stackStart, taskID);
|
||||
return LOS_NOK;
|
||||
}
|
||||
@@ -241,7 +252,7 @@ VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP)
|
||||
STATIC INLINE BOOL OsInsIsJump(UINTPTR addr)
|
||||
{
|
||||
UINT16 ins1 = *((UINT16 *)addr);
|
||||
UINT16 ins2 = *((UINT16 *)(addr + 2));
|
||||
UINT16 ins2 = *((UINT16 *)(addr + 2)); // 2, for the mask
|
||||
|
||||
/* Jal ins */
|
||||
if (((ins1 & OS_JALX_INS_MASK) == OS_JAL_INS_LOW) ||
|
||||
@@ -402,7 +413,7 @@ VOID LOS_BackTrace(VOID)
|
||||
if (LR[index] == 0) {
|
||||
break;
|
||||
}
|
||||
PRINTK("traceback %d -- lr = 0x%x\r\n", index, LR[index]);
|
||||
PRINTK("traceback %u -- lr = 0x%x\r\n", index, LR[index]);
|
||||
}
|
||||
PRINTK("----- traceback end -----\r\n");
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ extern "C" {
|
||||
#pragma section=CSTACK_SECTION_NAME
|
||||
|
||||
/* Default only one code section. In fact, there may be more than one.
|
||||
You can define more than one and modify the OsStackDataIsCodeAddr function
|
||||
You can define more than one and redefine the OsStackDataIsCodeAddr function
|
||||
to support searching in multiple code sections */
|
||||
#define CODE_START_ADDR ((UINTPTR)__section_begin(CODE_SECTION_NAME))
|
||||
#define CODE_END_ADDR ((UINTPTR)__section_end(CODE_SECTION_NAME))
|
||||
@@ -84,7 +84,7 @@ extern CHAR *CODE_SECTION_START(CODE_SECTION_NAME);
|
||||
extern CHAR *CODE_SECTION_END(CODE_SECTION_NAME);
|
||||
|
||||
/* Default only one code section. In fact, there may be more than one.
|
||||
You can define more than one and modify the OsStackDataIsCodeAddr function
|
||||
You can define more than one and redefine the OsStackDataIsCodeAddr function
|
||||
to support searching in multiple code sections */
|
||||
#define CODE_START_ADDR ((UINTPTR)&CODE_SECTION_START(CODE_SECTION_NAME))
|
||||
#define CODE_END_ADDR ((UINTPTR)&CODE_SECTION_END(CODE_SECTION_NAME))
|
||||
@@ -106,7 +106,7 @@ extern CHAR *CSTACK_SECTION_START;
|
||||
extern CHAR *CSTACK_SECTION_END;
|
||||
|
||||
/* Default only one code section. In fact, there may be more than one.
|
||||
You can define more than one and modify the OsStackDataIsCodeAddr function
|
||||
You can define more than one and redefine the OsStackDataIsCodeAddr function
|
||||
to support searching in multiple code sections */
|
||||
#define CODE_START_ADDR ((UINTPTR)&CODE_SECTION_START)
|
||||
#define CODE_END_ADDR ((UINTPTR)&CODE_SECTION_END)
|
||||
@@ -140,17 +140,6 @@ extern CHAR *CSTACK_SECTION_END;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* This function is used to judge whether the data in the stack is a code section address.
|
||||
The default code section is only one, but there may be more than one. Modify the
|
||||
judgment condition to support multiple code sections. */
|
||||
STATIC INLINE BOOL OsStackDataIsCodeAddr(UINTPTR value)
|
||||
{
|
||||
if ((value >= CODE_START_ADDR) && (value < CODE_END_ADDR)) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* This function is currently used to register the memory leak check hook,
|
||||
other uses do not need to be called temporarily. */
|
||||
VOID OSBackTraceInit(VOID);
|
||||
|
||||
@@ -27,8 +27,10 @@
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import("//kernel/liteos_m/config.gni")
|
||||
|
||||
static_library("cppsupport") {
|
||||
sources = [ "los_cppsupport.c" ]
|
||||
|
||||
include_dirs = [ "../../utils" ]
|
||||
configs += [ "$LITEOSTOPDIR:los_config" ]
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
|
||||
#include "los_cppsupport.h"
|
||||
|
||||
|
||||
typedef VOID (*InitFunc)(VOID);
|
||||
|
||||
INT32 LOS_CppSystemInit(UINTPTR initArrayStart, UINTPTR initArrayEnd)
|
||||
@@ -39,12 +38,10 @@ INT32 LOS_CppSystemInit(UINTPTR initArrayStart, UINTPTR initArrayEnd)
|
||||
UINTPTR *start;
|
||||
InitFunc initFunc = NULL;
|
||||
|
||||
for (start = (UINTPTR *)initArrayStart; start < (UINTPTR *)initArrayEnd; start++){
|
||||
for (start = (UINTPTR *)initArrayStart; start < (UINTPTR *)initArrayEnd; start++) {
|
||||
initFunc = (InitFunc)(*start);
|
||||
initFunc();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -27,13 +27,10 @@
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import("//kernel/liteos_m/config.gni")
|
||||
|
||||
static_library("cpup") {
|
||||
sources = [ "los_cpup.c" ]
|
||||
|
||||
include_dirs = [
|
||||
"../../kernel/include",
|
||||
"../../kernel/arch/include",
|
||||
"../../utils",
|
||||
"//third_party/bounds_checking_function/include",
|
||||
]
|
||||
configs += [ "$LITEOSTOPDIR:los_config" ]
|
||||
}
|
||||
|
||||
@@ -481,7 +481,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CpupUsageMonitor(CPUP_TYPE_E type, CPUP_MODE_E
|
||||
PRINTK("\nSysCpuUsage in <1s: ");
|
||||
}
|
||||
ret = LOS_HistorySysCpuUsage(mode);
|
||||
PRINTK("%d.%d", ret / LOS_CPUP_PRECISION_MULT, ret % LOS_CPUP_PRECISION_MULT);
|
||||
PRINTK("%u.%u", ret / LOS_CPUP_PRECISION_MULT, ret % LOS_CPUP_PRECISION_MULT);
|
||||
break;
|
||||
|
||||
case TASK_CPU_USAGE:
|
||||
@@ -495,11 +495,11 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CpupUsageMonitor(CPUP_TYPE_E type, CPUP_MODE_E
|
||||
return OS_ERROR;
|
||||
}
|
||||
if (mode == CPUP_IN_10S) {
|
||||
PRINTK("\nCPUusage of taskID %d in 10s: ", taskID);
|
||||
PRINTK("\nCPUusage of taskID %u in 10s: ", taskID);
|
||||
} else if (mode == CPUP_IN_1S) {
|
||||
PRINTK("\nCPUusage of taskID %d in 1s: ", taskID);
|
||||
PRINTK("\nCPUusage of taskID %u in 1s: ", taskID);
|
||||
} else {
|
||||
PRINTK("\nCPUusage of taskID %d in <1s: ", taskID);
|
||||
PRINTK("\nCPUusage of taskID %u in <1s: ", taskID);
|
||||
}
|
||||
ret = LOS_HistoryTaskCpuUsage(taskID, mode);
|
||||
PRINTK("%u.%u", ret / LOS_CPUP_PRECISION_MULT, ret % LOS_CPUP_PRECISION_MULT);
|
||||
|
||||
48
components/dynlink/BUILD.gn
Normal file
48
components/dynlink/BUILD.gn
Normal file
@@ -0,0 +1,48 @@
|
||||
# Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
# of conditions and the following disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
# to endorse or promote products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import("//kernel/liteos_m/config.gni")
|
||||
|
||||
config("dynlink_config") {
|
||||
include_dirs = [ "./" ]
|
||||
if (arch == "arm") {
|
||||
include_dirs += [ "../../kernel/arch/arm/include" ]
|
||||
} else {
|
||||
assert(false,
|
||||
"Dynlink module does not support for other archs except for arm!")
|
||||
}
|
||||
}
|
||||
|
||||
static_library("dynlink") {
|
||||
sources = [ "los_dynlink.c" ]
|
||||
|
||||
public_configs = [ ":dynlink_config" ]
|
||||
configs += [ "$LITEOSTOPDIR:los_config" ]
|
||||
|
||||
deps = [ "//kernel/liteos_m/kal/posix" ]
|
||||
}
|
||||
935
components/dynlink/los_dynlink.c
Executable file
935
components/dynlink/los_dynlink.c
Executable file
@@ -0,0 +1,935 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "los_dynlink.h"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include "unistd.h"
|
||||
#include "fcntl.h"
|
||||
#include "errno.h"
|
||||
#include "limits.h"
|
||||
#include "sys/stat.h"
|
||||
#include "securec.h"
|
||||
#include "arch_elf.h"
|
||||
#include "los_task.h"
|
||||
#include "los_debug.h"
|
||||
#include "los_mux.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if (LOSCFG_DYNLINK == 1)
|
||||
|
||||
#if defined(__ICCARM__) || defined(__CC_ARM)
|
||||
/**
|
||||
* Place instructions below in .icf linker file:
|
||||
*
|
||||
* keep {section .TABLE.START};
|
||||
* keep {section .sym.*};
|
||||
* keep {section .table.end};
|
||||
* define block SYMBOL_TABLE with fixed order
|
||||
* {
|
||||
* section .TABLE.START,
|
||||
* section .sym.*,
|
||||
* section .table.end
|
||||
* };
|
||||
* place in ROM_region {readonly, block SYMBOL_TABLE};
|
||||
*/
|
||||
const SymInfo symTableStart __attribute__((section(".TABLE.START"))) = {
|
||||
.name = "start",
|
||||
.addr = 0
|
||||
};
|
||||
|
||||
const SymInfo symTableEnd __attribute__((section(".table.end"))) = {
|
||||
.name = "end",
|
||||
.addr = 0
|
||||
};
|
||||
#pragma section=".TABLE.START"
|
||||
#pragma section=".table.end"
|
||||
#elif defined(__CLANG_ARM) || defined(__GNUC__)
|
||||
/**
|
||||
* Place instructions below in rodata segment of .ld linker file:
|
||||
*
|
||||
* __sym_table_start = .;
|
||||
* KEEP(*( SORT (.sym.*)));
|
||||
* __sym_table_end = .;
|
||||
*/
|
||||
extern char __sym_table_start[];
|
||||
extern char __sym_table_end[];
|
||||
#else
|
||||
#error Unknown compiler.
|
||||
#endif
|
||||
|
||||
STATIC LOS_DL_LIST g_dynSharedObjLink;
|
||||
STATIC UINT32 g_dynlinkMux;
|
||||
|
||||
STATIC DynSharedObj *OsIsPreLoaded(const CHAR *fileName)
|
||||
{
|
||||
DynSharedObj *dso = NULL;
|
||||
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(dso, &g_dynSharedObjLink, DynSharedObj, dsoNode) {
|
||||
if (!strcmp(fileName, dso->fileName)) {
|
||||
++dso->ref;
|
||||
return dso;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STATIC INT32 OsVerifyEhdr(const LD_ELF_EHDR *ehdr, UINT32 fileLen)
|
||||
{
|
||||
if (memcmp(ehdr->e_ident, LD_ELFMAG, LD_SELFMAG) != LOS_OK) {
|
||||
PRINT_ERR("The file is not elf format\n");
|
||||
return LOS_NOK;
|
||||
}
|
||||
if (ehdr->e_type != ET_DYN) {
|
||||
PRINT_ERR("The file is not shared library\n");
|
||||
return LOS_NOK;
|
||||
}
|
||||
if (!check_arch(ehdr)) {
|
||||
PRINT_ERR("The file can not load in current platform\n");
|
||||
return LOS_NOK;
|
||||
}
|
||||
if (ehdr->e_phnum > PHDR_NUM_MAX) {
|
||||
PRINT_ERR("The num of program header is out of limit\n");
|
||||
return LOS_NOK;
|
||||
}
|
||||
if (ehdr->e_phoff > fileLen) {
|
||||
PRINT_ERR("The offset of program header is invalid, elf file is bad\n");
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC INT32 OsReadELFInfo(INT32 fd, UINT8 *buffer, size_t readSize, off_t offset)
|
||||
{
|
||||
ssize_t byteNum;
|
||||
off_t returnPos;
|
||||
|
||||
if (readSize > 0) {
|
||||
returnPos = lseek(fd, offset, SEEK_SET);
|
||||
if (returnPos != offset) {
|
||||
PRINT_ERR("Failed to seek the position!, offset: %#x\n", offset);
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
byteNum = read(fd, buffer, readSize);
|
||||
if (byteNum <= 0) {
|
||||
PRINT_ERR("Failed to read from offset: %#x!\n", offset);
|
||||
return LOS_NOK;
|
||||
}
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC INT32 OsGetFileLength(UINT32 *fileLen, const CHAR *fileName)
|
||||
{
|
||||
struct stat buf;
|
||||
INT32 ret;
|
||||
|
||||
ret = stat(fileName, &buf);
|
||||
if (ret < 0) {
|
||||
PRINT_ERR("Failed to stat file: %s, errno: %d\n", fileName, errno);
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
if (buf.st_size > FILE_LENGTH_MAX) {
|
||||
PRINT_ERR("The file: %s length is out of limit!\n", fileName);
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
*fileLen = (UINT32)buf.st_size;
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC INT32 OsReadEhdr(INT32 fd, UINT32 fileLen, DynLinkInfo *dlInfo)
|
||||
{
|
||||
INT32 ret;
|
||||
|
||||
ret = OsReadELFInfo(fd, (UINT8 *)&dlInfo->elfEhdr, sizeof(LD_ELF_EHDR), 0);
|
||||
if (ret != LOS_OK) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ret = OsVerifyEhdr(&dlInfo->elfEhdr, fileLen);
|
||||
if (ret != LOS_OK) {
|
||||
return -ELIBBAD;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC INT32 OsReadPhdrs(INT32 fd, UINT32 fileLen, DynLinkInfo *dlInfo)
|
||||
{
|
||||
INT32 ret;
|
||||
UINT32 size;
|
||||
LD_ELF_EHDR *ehdr = &dlInfo->elfEhdr;
|
||||
|
||||
if ((ehdr->e_phnum == 0) || (ehdr->e_phentsize != sizeof(LD_ELF_PHDR))) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
size = sizeof(LD_ELF_PHDR) * ehdr->e_phnum;
|
||||
if ((ehdr->e_phoff + size) > fileLen) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
dlInfo->elfPhdr = (LD_ELF_PHDR *)LOS_MemAlloc(OS_SYS_MEM_ADDR, size);
|
||||
if (dlInfo->elfPhdr == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = OsReadELFInfo(fd, (UINT8 *)dlInfo->elfPhdr, size, ehdr->e_phoff);
|
||||
if (ret != LOS_OK) {
|
||||
LOS_MemFree(OS_SYS_MEM_ADDR, dlInfo->elfPhdr);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
|
||||
ERR:
|
||||
PRINT_ERR("the file is bad\n");
|
||||
return -ELIBBAD;
|
||||
}
|
||||
|
||||
STATIC DynSharedObj *OsLoadInit(const CHAR *fileName, VOID *pool)
|
||||
{
|
||||
DynSharedObj *dso = NULL;
|
||||
UINT32 allocSize, nameLen;
|
||||
UINT32 fileLen = 0;
|
||||
INT32 ret;
|
||||
|
||||
nameLen = strlen(fileName);
|
||||
if (nameLen > PATH_MAX) {
|
||||
PRINT_ERR("file name length is too long\n");
|
||||
errno = ENAMETOOLONG;
|
||||
return NULL;
|
||||
}
|
||||
allocSize = sizeof(DynSharedObj) + nameLen + 1;
|
||||
|
||||
dso = (DynSharedObj *)LOS_MemAlloc(OS_SYS_MEM_ADDR, allocSize);
|
||||
if (dso == NULL) {
|
||||
PRINT_ERR("failed to alloc for dso\n");
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
(VOID)memset_s(dso, allocSize, 0, allocSize);
|
||||
|
||||
dso->dlInfo = (DynLinkInfo *)LOS_MemAlloc(OS_SYS_MEM_ADDR, sizeof(DynLinkInfo));
|
||||
if (dso->dlInfo == NULL) {
|
||||
LOS_MemFree(OS_SYS_MEM_ADDR, dso);
|
||||
PRINT_ERR("failed to alloc for loadInfo\n");
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
(VOID)memset_s(dso->dlInfo, sizeof(DynLinkInfo), 0, sizeof(DynLinkInfo));
|
||||
|
||||
ret = OsGetFileLength(&fileLen, fileName);
|
||||
if (ret != LOS_OK) {
|
||||
errno = ENOENT;
|
||||
goto ERR1;
|
||||
}
|
||||
|
||||
dso->fd = open(fileName, O_RDONLY);
|
||||
if (dso->fd < 0) {
|
||||
PRINT_ERR("Failed to open ELF file: %s!\n", fileName);
|
||||
goto ERR1;
|
||||
}
|
||||
|
||||
ret = OsReadEhdr(dso->fd, fileLen, dso->dlInfo);
|
||||
if (ret != LOS_OK) {
|
||||
errno = -ret;
|
||||
goto ERR2;
|
||||
}
|
||||
|
||||
ret = OsReadPhdrs(dso->fd, fileLen, dso->dlInfo);
|
||||
if (ret != LOS_OK) {
|
||||
errno = -ret;
|
||||
goto ERR2;
|
||||
}
|
||||
|
||||
strcpy(dso->buf, fileName);
|
||||
dso->fileName = dso->buf;
|
||||
dso->ref = 1;
|
||||
dso->pool = (pool ? pool : OS_SYS_MEM_ADDR);
|
||||
LOS_ListInit(&dso->dsoNode);
|
||||
|
||||
return dso;
|
||||
|
||||
ERR2:
|
||||
close(dso->fd);
|
||||
ERR1:
|
||||
LOS_MemFree(OS_SYS_MEM_ADDR, dso->dlInfo);
|
||||
LOS_MemFree(OS_SYS_MEM_ADDR, dso);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STATIC INT32 OsReserveSpace(const DynLinkInfo *dlInfo, UINT32 *boundary)
|
||||
{
|
||||
const LD_ELF_PHDR *elfPhdrTemp = dlInfo->elfPhdr;
|
||||
INT32 phdrNum = dlInfo->elfEhdr.e_phnum;
|
||||
UINTPTR addrMin = SIZE_MAX;
|
||||
UINTPTR addrMax = 0;
|
||||
UINT32 offStart = 0;
|
||||
UINT64 size;
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < phdrNum; ++i, ++elfPhdrTemp) {
|
||||
if (elfPhdrTemp->p_type == PT_TLS) {
|
||||
PRINT_ERR("unsupport tls\n");
|
||||
return 0;
|
||||
}
|
||||
if (elfPhdrTemp->p_type != PT_LOAD) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*boundary == 0) {
|
||||
*boundary = elfPhdrTemp->p_align;
|
||||
}
|
||||
|
||||
if (elfPhdrTemp->p_vaddr < addrMin) {
|
||||
addrMin = elfPhdrTemp->p_vaddr;
|
||||
offStart = elfPhdrTemp->p_offset;
|
||||
}
|
||||
if ((elfPhdrTemp->p_vaddr + elfPhdrTemp->p_memsz) > addrMax) {
|
||||
addrMax = elfPhdrTemp->p_vaddr + elfPhdrTemp->p_memsz;
|
||||
}
|
||||
}
|
||||
|
||||
if ((addrMin == addrMax) || (addrMax < addrMin)) {
|
||||
return 0;
|
||||
}
|
||||
size = ELF_ALIGN_UP(addrMax, *boundary) - ELF_ALIGN_DOWN(addrMin, *boundary) + ELF_ALIGN_DOWN(offStart, *boundary);
|
||||
|
||||
return (size > UINT_MAX) ? 0 : (UINT32)size;
|
||||
}
|
||||
|
||||
STATIC UINTPTR OsDoLoadFile(INT32 fd, UINTPTR addr, const LD_ELF_PHDR *elfPhdr, UINT32 boundary)
|
||||
{
|
||||
INT32 ret;
|
||||
UINT32 offset = elfPhdr->p_offset - ELF_ALIGN_OFFSET(elfPhdr->p_vaddr, boundary);
|
||||
UINT32 size = elfPhdr->p_filesz + ELF_ALIGN_OFFSET(elfPhdr->p_vaddr, boundary);
|
||||
if (size == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
addr = ELF_ALIGN_DOWN(addr, boundary);
|
||||
ret = OsReadELFInfo(fd, (UINT8 *)addr, size, offset);
|
||||
if (ret != LOS_OK) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
STATIC INT32 OsLoadELFFile(DynSharedObj *dso, UINT32 boundary)
|
||||
{
|
||||
DynLinkInfo *dlInfo = dso->dlInfo;
|
||||
const LD_ELF_PHDR *elfPhdrTemp = dlInfo->elfPhdr;
|
||||
const LD_ELF_EHDR *elfEhdr = &dlInfo->elfEhdr;
|
||||
UINTPTR loadBase = dso->loadBase;
|
||||
UINTPTR vAddr, loadAddr, bssStart, bssEnd;
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < elfEhdr->e_phnum; ++i, ++elfPhdrTemp) {
|
||||
if (elfPhdrTemp->p_type != PT_LOAD) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((elfPhdrTemp->p_flags & PF_R) == 0) {
|
||||
return -ENOEXEC;
|
||||
}
|
||||
vAddr = elfPhdrTemp->p_vaddr;
|
||||
|
||||
loadAddr = OsDoLoadFile(dso->fd, (vAddr + loadBase), elfPhdrTemp, boundary);
|
||||
if (loadAddr == 0) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if ((elfPhdrTemp->p_memsz > elfPhdrTemp->p_filesz) && (elfPhdrTemp->p_flags & PF_W)) {
|
||||
bssStart = loadAddr + ELF_ALIGN_OFFSET(vAddr, boundary) + elfPhdrTemp->p_filesz;
|
||||
bssEnd = loadAddr + ELF_ALIGN_OFFSET(vAddr, boundary) + elfPhdrTemp->p_memsz;
|
||||
(VOID)memset_s((VOID *)bssStart, bssEnd - bssStart, 0, bssEnd - bssStart);
|
||||
}
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC INT32 OsLoadLibrary(DynSharedObj *dso)
|
||||
{
|
||||
UINT32 loadSize;
|
||||
UINT32 boundary = 0;
|
||||
INT32 ret;
|
||||
|
||||
loadSize = OsReserveSpace(dso->dlInfo, &boundary);
|
||||
if (loadSize == 0) {
|
||||
PRINT_ERR("failed to reserve space!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dso->loadBase = (UINTPTR)LOS_MemAllocAlign(dso->pool, loadSize, boundary);
|
||||
if (dso->loadBase == 0) {
|
||||
PRINT_ERR("failed to alloc memory for loading shared library\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = OsLoadELFFile(dso, boundary);
|
||||
if (ret != LOS_OK) {
|
||||
LOS_MemFree(dso->pool, (VOID *)dso->loadBase);
|
||||
PRINT_ERR("failed to load shared library\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC INT32 OsGetDynBase(DynSharedObj *dso)
|
||||
{
|
||||
DynLinkInfo *dlInfo = dso->dlInfo;
|
||||
const LD_ELF_PHDR *elfPhdrTemp = dlInfo->elfPhdr;
|
||||
INT32 phdrNum = dlInfo->elfEhdr.e_phnum;
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < phdrNum; ++i, ++elfPhdrTemp) {
|
||||
if (elfPhdrTemp->p_type != PT_DYNAMIC) {
|
||||
continue;
|
||||
}
|
||||
dlInfo->dynBase = dso->loadBase + elfPhdrTemp->p_vaddr;
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
STATIC INT32 OsParseDynamic(DynSharedObj *dso)
|
||||
{
|
||||
LD_ELF_DYN *dyn = NULL;
|
||||
DynLinkInfo *dlInfo = dso->dlInfo;
|
||||
RelocInfoTab *relInfoTab = &dlInfo->relInfoTab;
|
||||
|
||||
for (dyn = (LD_ELF_DYN *)dlInfo->dynBase; dyn->d_tag != DT_NULL; ++dyn) {
|
||||
switch (dyn->d_tag) {
|
||||
case DT_NEEDED:
|
||||
PRINT_ERR("shared library should not depend on others\n");
|
||||
return -ENOTSUP;
|
||||
case DT_TEXTREL:
|
||||
PRINT_ERR("you should recompile shared library with -fPIC\n");
|
||||
return -EFAULT;
|
||||
case DT_HASH:
|
||||
dlInfo->hashTab = (UINT32 *)(dso->loadBase + dyn->d_un.d_ptr);
|
||||
break;
|
||||
case DT_SYMTAB:
|
||||
dlInfo->symTab = (LD_ELF_SYM *)(dso->loadBase + dyn->d_un.d_ptr);
|
||||
break;
|
||||
case DT_STRTAB:
|
||||
dlInfo->symStrings = (CHAR *)(dso->loadBase + dyn->d_un.d_ptr);
|
||||
break;
|
||||
case DT_REL:
|
||||
relInfoTab->rel.relTab = dso->loadBase + dyn->d_un.d_ptr;
|
||||
relInfoTab->rel.relEntSize = sizeof(LD_ELF_REL);
|
||||
break;
|
||||
case DT_RELSZ:
|
||||
relInfoTab->rel.relTabSize = dyn->d_un.d_val;
|
||||
break;
|
||||
case DT_RELA:
|
||||
relInfoTab->rela.relTab = dso->loadBase + dyn->d_un.d_ptr;
|
||||
relInfoTab->rela.relEntSize = sizeof(LD_ELF_RELA);
|
||||
break;
|
||||
case DT_RELASZ:
|
||||
relInfoTab->rela.relTabSize = dyn->d_un.d_val;
|
||||
break;
|
||||
case DT_JMPREL:
|
||||
relInfoTab->jmpRel.relTab = dso->loadBase + dyn->d_un.d_ptr;
|
||||
break;
|
||||
case DT_PLTRELSZ:
|
||||
relInfoTab->jmpRel.relTabSize = dyn->d_un.d_val;
|
||||
break;
|
||||
case DT_PLTREL:
|
||||
relInfoTab->jmpRel.relEntSize = (dyn->d_un.d_val == DT_REL) ? sizeof(LD_ELF_REL) : sizeof(LD_ELF_RELA);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC UINT32 OsGetHashVal(const CHAR *name)
|
||||
{
|
||||
UINT32 hashVal = 0;
|
||||
UINT32 tmp;
|
||||
const UINT8 *str = (const UINT8 *)name;
|
||||
|
||||
while (*str) {
|
||||
hashVal = (*str) + (hashVal << WORD_SHIFT);
|
||||
tmp = hashVal & HASH_MASK;
|
||||
if (tmp != 0) {
|
||||
hashVal ^= tmp >> HASH_SHIFT;
|
||||
}
|
||||
|
||||
hashVal &= ~tmp;
|
||||
++str;
|
||||
}
|
||||
|
||||
return hashVal;
|
||||
}
|
||||
|
||||
STATIC LD_ELF_SYM *OsFindSymInDso(const DynLinkInfo *dlInfo, const CHAR *name)
|
||||
{
|
||||
LD_ELF_SYM *symTab = dlInfo->symTab;
|
||||
LD_ELF_SYM *sym = NULL;
|
||||
CHAR *symStr = dlInfo->symStrings;
|
||||
UINT32 *hashTab = dlInfo->hashTab;
|
||||
UINT32 bucketNum = hashTab[0];
|
||||
UINT32 *bucket = &hashTab[BUCKET_IDX];
|
||||
UINT32 *chain = &bucket[bucketNum];
|
||||
UINT32 hashVal = OsGetHashVal(name);
|
||||
UINT32 symIdx;
|
||||
|
||||
for (symIdx = bucket[hashVal % bucketNum]; symIdx; symIdx = chain[symIdx]) {
|
||||
if (strcmp(name, symStr + symTab[symIdx].st_name) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sym = symTab + symIdx;
|
||||
if ((sym->st_value == 0) || (sym->st_shndx == 0)) {
|
||||
return NULL;
|
||||
}
|
||||
return symTab + symIdx;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STATIC SymInfo *OsFindSymInTable(const CHAR *name)
|
||||
{
|
||||
#if defined(__ICCARM__) || defined(__CC_ARM)
|
||||
SymInfo *symTab = (SymInfo *)__section_end(".TABLE.START");
|
||||
UINT32 symTableSize = ((UINTPTR)__section_begin(".table.end") -
|
||||
(UINTPTR)__section_end(".TABLE.START")) / sizeof(SymInfo);
|
||||
#elif defined(__CLANG_ARM) || defined(__GNUC__)
|
||||
SymInfo *symTab = (SymInfo *)__sym_table_start;
|
||||
UINT32 symTableSize = (__sym_table_end - __sym_table_start) / sizeof(SymInfo);
|
||||
#endif
|
||||
INT32 startIdx = 0;
|
||||
INT32 endIdx = symTableSize - 1;
|
||||
INT32 ret, midIdx;
|
||||
|
||||
while (startIdx <= endIdx) {
|
||||
midIdx = startIdx + ((UINT32)(endIdx - startIdx) >> 1);
|
||||
ret = strcmp(symTab[midIdx].name, name);
|
||||
if (ret > 0) {
|
||||
endIdx = midIdx - 1;
|
||||
} else if (ret < 0) {
|
||||
startIdx = midIdx + 1;
|
||||
} else {
|
||||
return symTab + midIdx;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STATIC UINTPTR OsFindSym(const DynSharedObj *dso, INT32 symIdx)
|
||||
{
|
||||
DynLinkInfo *dlInfo = dso->dlInfo;
|
||||
CHAR *symStrings = dlInfo->symStrings;
|
||||
CHAR *symStr = NULL;
|
||||
LD_ELF_SYM *symTab = dlInfo->symTab;
|
||||
LD_ELF_SYM *sym = NULL;
|
||||
LD_ELF_SYM *symInDso = NULL;
|
||||
SymInfo *symInTab = NULL;
|
||||
|
||||
sym = symTab + symIdx;
|
||||
symStr = symStrings + sym->st_name;
|
||||
if ((symInDso = OsFindSymInDso(dlInfo, symStr)) != NULL) {
|
||||
return dso->loadBase + symInDso->st_value;
|
||||
} else if ((symInTab = OsFindSymInTable(symStr)) != NULL) {
|
||||
return symInTab->addr;
|
||||
} else {
|
||||
PRINT_ERR("failed to relocate %s, symbol: %s not found\n", dso->fileName, symStr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
STATIC INT32 OsDoReloc(const DynSharedObj *dso, INT32 type, UINTPTR relocAddr, UINT32 addend, UINTPTR symAddr)
|
||||
{
|
||||
switch (type) {
|
||||
case R_ARCH_NONE:
|
||||
break;
|
||||
case R_ARCH_GLOB_DAT:
|
||||
case R_ARCH_JUMP_SLOT:
|
||||
*(UINTPTR *)relocAddr = symAddr + addend;
|
||||
break;
|
||||
case R_ARCH_ABS32:
|
||||
*(UINTPTR *)relocAddr = symAddr + ((addend != 0) ? addend : *(UINTPTR *)relocAddr);
|
||||
break;
|
||||
case R_ARCH_RELATIVE:
|
||||
*(UINTPTR *)relocAddr = dso->loadBase + ((addend != 0) ? addend : *(UINTPTR *)relocAddr);
|
||||
break;
|
||||
default:
|
||||
PRINT_ERR("failed to relocate %s, unsupported reloc type: %d\n", dso->fileName, type);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC INT32 OsDoRelocSyms(DynSharedObj *dso, RelocInfo *relInfo)
|
||||
{
|
||||
UINT32 relStride = relInfo->relEntSize / sizeof(UINT32);
|
||||
UINT32 *relTab = (UINT32 *)relInfo->relTab;
|
||||
UINT32 addend;
|
||||
UINTPTR relocAddr, symAddr;
|
||||
INT32 i, symIdx, ret, type;
|
||||
|
||||
for (i = 0; i < relInfo->relTabSize; i += relInfo->relEntSize, relTab += relStride) {
|
||||
type = REL_TYPE(relTab[1]);
|
||||
if (type == R_ARCH_NONE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
symIdx = REL_SYM(relTab[1]);
|
||||
if (symIdx == 0) {
|
||||
symAddr = 0;
|
||||
} else {
|
||||
symAddr = OsFindSym(dso, symIdx);
|
||||
if (symAddr == 0) {
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
relocAddr = dso->loadBase + relTab[0];
|
||||
addend = (relInfo->relEntSize == sizeof(LD_ELF_REL)) ? 0 : relTab[relStride - 1];
|
||||
ret = OsDoReloc(dso, type, relocAddr, addend, symAddr);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC INT32 OsRelocSyms(DynSharedObj *dso)
|
||||
{
|
||||
DynLinkInfo *dlInfo = dso->dlInfo;
|
||||
RelocInfo *relInfo = (RelocInfo *)&dlInfo->relInfoTab;
|
||||
INT32 relTypes = sizeof(RelocInfoTab) / sizeof(RelocInfo);
|
||||
INT32 i, ret;
|
||||
|
||||
for (i = 0; i < relTypes; ++i, ++relInfo) {
|
||||
if (relInfo->relTab == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = OsDoRelocSyms(dso, relInfo);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC INT32 OsDoDynLink(DynSharedObj *dso)
|
||||
{
|
||||
INT32 ret;
|
||||
|
||||
ret = OsGetDynBase(dso);
|
||||
if (ret != LOS_OK) {
|
||||
PRINT_ERR("there are no dynamic segments in elf file\n");
|
||||
return -ELIBBAD;
|
||||
}
|
||||
|
||||
ret = OsParseDynamic(dso);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = OsRelocSyms(dso);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC VOID OsDeLoadInit(DynSharedObj *dso)
|
||||
{
|
||||
LOS_MemFree(OS_SYS_MEM_ADDR, dso->dlInfo->elfPhdr);
|
||||
dso->dlInfo->elfPhdr = NULL;
|
||||
close(dso->fd);
|
||||
}
|
||||
|
||||
STATIC VOID OsGetInitFini(DynSharedObj *dso)
|
||||
{
|
||||
LD_ELF_DYN *dyn = NULL;
|
||||
DynLinkInfo *dlInfo = dso->dlInfo;
|
||||
InitFiniTab *initFiniTab = &dso->initFiniTab;
|
||||
|
||||
for (dyn = (LD_ELF_DYN *)dlInfo->dynBase; dyn->d_tag != DT_NULL; ++dyn) {
|
||||
switch (dyn->d_tag) {
|
||||
case DT_INIT:
|
||||
initFiniTab->init.func = dyn->d_un.d_ptr;
|
||||
break;
|
||||
case DT_INIT_ARRAY:
|
||||
initFiniTab->init.array = dyn->d_un.d_ptr;
|
||||
break;
|
||||
case DT_INIT_ARRAYSZ:
|
||||
initFiniTab->init.arraySz = dyn->d_un.d_val;
|
||||
break;
|
||||
case DT_FINI:
|
||||
initFiniTab->fini.func = dyn->d_un.d_ptr;
|
||||
break;
|
||||
case DT_FINI_ARRAY:
|
||||
initFiniTab->fini.array = dyn->d_un.d_ptr;
|
||||
break;
|
||||
case DT_FINI_ARRAYSZ:
|
||||
initFiniTab->fini.arraySz = dyn->d_un.d_val;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC VOID OsDoInit(DynSharedObj *dso)
|
||||
{
|
||||
InitFiniTab *initFiniTab = &dso->initFiniTab;
|
||||
INIT_FINI_FUNC initFunc = NULL;
|
||||
UINTPTR *func = NULL;
|
||||
UINT32 funcNum;
|
||||
|
||||
OsGetInitFini(dso);
|
||||
if (initFiniTab->init.func != 0) {
|
||||
initFunc = (INIT_FINI_FUNC)(dso->loadBase + initFiniTab->init.func);
|
||||
initFunc();
|
||||
}
|
||||
|
||||
if (initFiniTab->init.array == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
funcNum = initFiniTab->init.arraySz / sizeof(UINTPTR);
|
||||
func = (UINTPTR *)(dso->loadBase + initFiniTab->init.array);
|
||||
while (funcNum--) {
|
||||
initFunc = (INIT_FINI_FUNC)(*func);
|
||||
initFunc();
|
||||
++func;
|
||||
}
|
||||
}
|
||||
|
||||
VOID *LOS_SoLoad(const CHAR *fileName, VOID *pool)
|
||||
{
|
||||
INT32 ret;
|
||||
DynSharedObj *dso = NULL;
|
||||
|
||||
if (fileName == NULL) {
|
||||
PRINT_ERR("invalid file name\n");
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxPend(g_dynlinkMux, LOS_WAIT_FOREVER);
|
||||
dso = OsIsPreLoaded(fileName);
|
||||
if (dso != NULL) {
|
||||
(VOID)LOS_MuxPost(g_dynlinkMux);
|
||||
return dso;
|
||||
}
|
||||
|
||||
dso = OsLoadInit(fileName, pool);
|
||||
if (dso == NULL) {
|
||||
(VOID)LOS_MuxPost(g_dynlinkMux);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = OsLoadLibrary(dso);
|
||||
if (ret != LOS_OK) {
|
||||
errno = -ret;
|
||||
goto ERR1;
|
||||
}
|
||||
|
||||
ret = OsDoDynLink(dso);
|
||||
if (ret != LOS_OK) {
|
||||
errno = -ret;
|
||||
goto ERR2;
|
||||
}
|
||||
|
||||
OsDoInit(dso);
|
||||
|
||||
LOS_ListAdd(&g_dynSharedObjLink, &dso->dsoNode);
|
||||
(VOID)LOS_MuxPost(g_dynlinkMux);
|
||||
OsDeLoadInit(dso);
|
||||
|
||||
return dso;
|
||||
|
||||
ERR2:
|
||||
LOS_MemFree(dso->pool, (VOID *)dso->loadBase);
|
||||
ERR1:
|
||||
close(dso->fd);
|
||||
(VOID)LOS_MuxPost(g_dynlinkMux);
|
||||
LOS_MemFree(OS_SYS_MEM_ADDR, dso->dlInfo->elfPhdr);
|
||||
LOS_MemFree(OS_SYS_MEM_ADDR, dso->dlInfo);
|
||||
LOS_MemFree(OS_SYS_MEM_ADDR, dso);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STATIC DynSharedObj *OsCheckHandle(VOID *handle)
|
||||
{
|
||||
DynSharedObj *dso = NULL;
|
||||
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(dso, &g_dynSharedObjLink, DynSharedObj, dsoNode) {
|
||||
if (handle == dso) {
|
||||
return dso;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VOID *LOS_FindSym(VOID *handle, const CHAR *name)
|
||||
{
|
||||
LD_ELF_SYM *sym = NULL;
|
||||
DynSharedObj *dso = NULL;
|
||||
VOID *symAddr = NULL;
|
||||
|
||||
if ((handle == NULL) || (name == NULL)) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxPend(g_dynlinkMux, LOS_WAIT_FOREVER);
|
||||
dso = OsCheckHandle(handle);
|
||||
if (dso == NULL) {
|
||||
(VOID)LOS_MuxPost(g_dynlinkMux);
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
sym = OsFindSymInDso(dso->dlInfo, name);
|
||||
if (sym == NULL) {
|
||||
(VOID)LOS_MuxPost(g_dynlinkMux);
|
||||
PRINT_ERR("failed to find symbol: %s\n", name);
|
||||
errno = EFAULT;
|
||||
return NULL;
|
||||
}
|
||||
symAddr = (VOID *)(dso->loadBase + sym->st_value);
|
||||
(VOID)LOS_MuxPost(g_dynlinkMux);
|
||||
return symAddr;
|
||||
|
||||
ERR:
|
||||
PRINT_ERR("invalid input param\n");
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STATIC VOID OsDoFini(DynSharedObj *dso)
|
||||
{
|
||||
InitFiniTab *initFiniTab = &dso->initFiniTab;
|
||||
INIT_FINI_FUNC finiFunc = NULL;
|
||||
UINTPTR *func = NULL;
|
||||
UINT32 funcNum;
|
||||
|
||||
if (initFiniTab->fini.array != 0) {
|
||||
funcNum = initFiniTab->fini.arraySz / sizeof(UINTPTR);
|
||||
func = (UINTPTR *)(dso->loadBase + initFiniTab->fini.array) + funcNum;
|
||||
while (funcNum--) {
|
||||
--func;
|
||||
finiFunc = (INIT_FINI_FUNC)(*func);
|
||||
finiFunc();
|
||||
}
|
||||
}
|
||||
|
||||
if (initFiniTab->fini.func != 0) {
|
||||
finiFunc = (INIT_FINI_FUNC)(dso->loadBase + initFiniTab->fini.func);
|
||||
finiFunc();
|
||||
}
|
||||
}
|
||||
|
||||
INT32 LOS_SoUnload(VOID *handle)
|
||||
{
|
||||
DynSharedObj *dso = NULL;
|
||||
|
||||
if (handle == NULL) {
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxPend(g_dynlinkMux, LOS_WAIT_FOREVER);
|
||||
dso = OsCheckHandle(handle);
|
||||
if (dso == NULL) {
|
||||
(VOID)LOS_MuxPost(g_dynlinkMux);
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
if (dso->ref > 1) {
|
||||
--dso->ref;
|
||||
(VOID)LOS_MuxPost(g_dynlinkMux);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
OsDoFini(dso);
|
||||
|
||||
LOS_ListDelete(&dso->dsoNode);
|
||||
(VOID)LOS_MuxPost(g_dynlinkMux);
|
||||
|
||||
LOS_MemFree(dso->pool, (VOID *)dso->loadBase);
|
||||
LOS_MemFree(OS_SYS_MEM_ADDR, dso->dlInfo);
|
||||
LOS_MemFree(OS_SYS_MEM_ADDR, dso);
|
||||
|
||||
return LOS_OK;
|
||||
ERR:
|
||||
PRINT_ERR("invalid handle\n");
|
||||
errno = EINVAL;
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
INT32 LOS_DynlinkInit(VOID)
|
||||
{
|
||||
UINT32 ret;
|
||||
|
||||
LOS_ListInit(&g_dynSharedObjLink);
|
||||
ret = LOS_MuxCreate(&g_dynlinkMux);
|
||||
if (ret != LOS_OK) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
#endif /* LOSCFG_DYNLINK */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
201
components/dynlink/los_dynlink.h
Executable file
201
components/dynlink/los_dynlink.h
Executable file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _LOS_DYNLINK_H
|
||||
#define _LOS_DYNLINK_H
|
||||
|
||||
#include "elf.h"
|
||||
#include "los_compiler.h"
|
||||
#include "los_list.h"
|
||||
#include "los_memory.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#ifdef LOSCFG_AARCH64
|
||||
typedef Elf64_Ehdr LD_ELF_EHDR;
|
||||
typedef Elf64_Phdr LD_ELF_PHDR;
|
||||
typedef Elf64_Sym LD_ELF_SYM;
|
||||
typedef Elf64_Dyn LD_ELF_DYN;
|
||||
typedef Elf64_Rel LD_ELF_REL;
|
||||
typedef Elf64_Rela LD_ELF_RELA;
|
||||
#define REL_TYPE(x) ELF64_R_TYPE(x)
|
||||
#define REL_SYM(x) ELF64_R_SYM(x)
|
||||
#define REL_INFO ELF64_R_INFO
|
||||
#else
|
||||
typedef Elf32_Ehdr LD_ELF_EHDR;
|
||||
typedef Elf32_Phdr LD_ELF_PHDR;
|
||||
typedef Elf32_Sym LD_ELF_SYM;
|
||||
typedef Elf32_Dyn LD_ELF_DYN;
|
||||
typedef Elf32_Rel LD_ELF_REL;
|
||||
typedef Elf32_Rela LD_ELF_RELA;
|
||||
#define REL_TYPE(x) ELF32_R_TYPE(x)
|
||||
#define REL_SYM(x) ELF32_R_SYM(x)
|
||||
#define REL_INFO ELF32_R_INFO
|
||||
#endif
|
||||
|
||||
#define LD_ELFMAG "\177ELF"
|
||||
#define LD_SELFMAG 4
|
||||
#define PHDR_NUM_MAX 128
|
||||
#define DYNAMIC_CNT 32
|
||||
#define HASH_MASK 0xf0000000
|
||||
#define WORD_SHIFT 4
|
||||
#define HASH_SHIFT 24
|
||||
#define BUCKET_IDX 2
|
||||
|
||||
#define ELF_ALIGN_UP(a, b) (((a) + ((b) - 1)) & ~((b) - 1))
|
||||
#define ELF_ALIGN_DOWN(a, b) ((a) & ~((b) - 1))
|
||||
#define ELF_ALIGN_OFFSET(a, b) ((a) & ((b) - 1))
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 256
|
||||
#endif
|
||||
#ifndef FILE_LENGTH_MAX
|
||||
#define FILE_LENGTH_MAX 0x40000
|
||||
#endif
|
||||
typedef VOID (*INIT_FINI_FUNC)(VOID);
|
||||
|
||||
typedef struct {
|
||||
UINTPTR relTab;
|
||||
UINT32 relTabSize;
|
||||
UINT32 relEntSize;
|
||||
} RelocInfo;
|
||||
|
||||
typedef struct {
|
||||
RelocInfo rel;
|
||||
RelocInfo rela;
|
||||
RelocInfo jmpRel;
|
||||
} RelocInfoTab;
|
||||
|
||||
typedef struct {
|
||||
UINTPTR func;
|
||||
UINTPTR array;
|
||||
UINT32 arraySz;
|
||||
} InitFiniInfo;
|
||||
|
||||
typedef struct {
|
||||
InitFiniInfo init;
|
||||
InitFiniInfo fini;
|
||||
} InitFiniTab;
|
||||
|
||||
typedef struct {
|
||||
LD_ELF_EHDR elfEhdr;
|
||||
LD_ELF_PHDR *elfPhdr;
|
||||
UINTPTR dynBase;
|
||||
UINT32 *hashTab;
|
||||
LD_ELF_SYM *symTab;
|
||||
CHAR *symStrings;
|
||||
RelocInfoTab relInfoTab;
|
||||
} DynLinkInfo;
|
||||
|
||||
typedef struct {
|
||||
CHAR *fileName;
|
||||
INT32 fd;
|
||||
DynLinkInfo *dlInfo;
|
||||
UINTPTR loadBase;
|
||||
InitFiniTab initFiniTab;
|
||||
LOS_DL_LIST dsoNode;
|
||||
UINT32 ref;
|
||||
VOID *pool;
|
||||
CHAR buf[];
|
||||
} DynSharedObj;
|
||||
|
||||
typedef struct {
|
||||
CHAR *name;
|
||||
UINTPTR addr;
|
||||
} SymInfo;
|
||||
|
||||
#define SYM_EXPORT(func) \
|
||||
const SymInfo sym_##func __attribute__((section(".sym."#func))) = { \
|
||||
.name = #func, \
|
||||
.addr = (UINTPTR)func \
|
||||
};
|
||||
|
||||
/*
|
||||
* @brief Load the shared library file named by the NULL-terminated string filename and
|
||||
* return a valid handle for the loaded library.
|
||||
*
|
||||
* @param fileName The name pointer of shared library.
|
||||
* @param pool The heap for shared library to load. If the parameter, pool, is NULL, then
|
||||
* the dynamic loader & linker module will use the default heap and the pool is not NULL,
|
||||
* then the shared library will be loaded to the heap by pool.
|
||||
*
|
||||
* @note When the heap, pool, is not NULL, you should call LOS_MemInit() to initialize the
|
||||
* pool before calling LOS_SoLoad(). By the way, the system will comsume a certain amount
|
||||
* of memory to initialize the pool. LOS_SoLoad must not be called in interrupt callback.
|
||||
*
|
||||
* @return Return NULL if error. Return non-NULL if success.
|
||||
*/
|
||||
VOID *LOS_SoLoad(const CHAR *fileName, VOID *pool);
|
||||
|
||||
/*
|
||||
* @brief Get the address of symbol named by the parameter, name, from the parameter, handle.
|
||||
*
|
||||
* @param handle The handle for the loaded shared library.
|
||||
* @param name The name of symbol to search.
|
||||
*
|
||||
* @note LOS_FindSym must not be called in interrupt callback.
|
||||
*
|
||||
* @return Return NULL if error. Return non-NULL if success.
|
||||
*/
|
||||
VOID *LOS_FindSym(VOID *handle, const CHAR *name);
|
||||
|
||||
/*
|
||||
* @brief Decrement the reference count on the loaded shared library refered to by handle.
|
||||
* If the reference count drops to zero, then the library is unloaded.
|
||||
*
|
||||
* This function validates that the handle is valid.
|
||||
*
|
||||
* @param handle The handle for the loaded shared library by LOS_SoLoad() interface.
|
||||
*
|
||||
* @note LOS_SoUnload must not be called in interrupt callback.
|
||||
*
|
||||
* @return Return 1 if error. Return 0 if success.
|
||||
*/
|
||||
INT32 LOS_SoUnload(VOID *handle);
|
||||
|
||||
/*
|
||||
* @brief Initialization for dynamic loader & linker module.
|
||||
*
|
||||
* @param VOID.
|
||||
*
|
||||
* @return Return LOS_NOK if error. Return LOS_OK if success.
|
||||
*/
|
||||
INT32 LOS_DynlinkInit(VOID);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_DYNLINK_H */
|
||||
|
||||
65
components/dynlink/script/so_parse
Executable file
65
components/dynlink/script/so_parse
Executable file
@@ -0,0 +1,65 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
# of conditions and the following disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
# to endorse or promote products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# Description: The script is used to calculate the memory size that the specified shared library
|
||||
# will occupy when loading to the RAM.
|
||||
|
||||
READELF=readelf
|
||||
RM=rm
|
||||
SIZE=0x0
|
||||
SIZE_ALL=0x0
|
||||
SIZE_MAX=0
|
||||
TMP_FILE=tmp.txt
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "Usage: ./so_parse lib.so"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
parse_line()
|
||||
{
|
||||
MEM_SIZE=$(echo $1 | awk '{print $6}')
|
||||
echo ${MEM_SIZE}
|
||||
}
|
||||
|
||||
${READELF} -l $1 | while read line; do
|
||||
HEAD_STRING=$(echo ${line} | awk '{print $1}')
|
||||
if [[ "${HEAD_STRING}" == *"LOAD"* ]]; then
|
||||
SIZE=`parse_line "${line}"`
|
||||
SIZE=`echo ${SIZE}`
|
||||
SIZE_ALL=$((SIZE_ALL+SIZE))
|
||||
fi
|
||||
echo ${SIZE_ALL} >> ${TMP_FILE}
|
||||
done
|
||||
|
||||
NEED_SIZE=`tail -n 1 ${TMP_FILE}`
|
||||
echo "${NEED_SIZE} kb memory to reserve for $1!"
|
||||
${RM} -f ${TMP_FILE}
|
||||
|
||||
@@ -27,15 +27,13 @@
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import("//kernel/liteos_m/config.gni")
|
||||
|
||||
static_library("exchook") {
|
||||
sources = [
|
||||
"los_exc_info.c",
|
||||
"los_exchook.c",
|
||||
]
|
||||
include_dirs = [
|
||||
"../../kernel/arch/include",
|
||||
"../../kernel/include",
|
||||
"../../utils",
|
||||
"//third_party/bounds_checking_function/include",
|
||||
]
|
||||
|
||||
configs += [ "$LITEOSTOPDIR:los_config" ]
|
||||
}
|
||||
|
||||
@@ -28,9 +28,7 @@
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
static_library("fs_operations") {
|
||||
sources = [
|
||||
"./fs.c",
|
||||
]
|
||||
sources = [ "./fs.c" ]
|
||||
|
||||
include_dirs = [
|
||||
"../../../kernel/arch/include",
|
||||
@@ -51,10 +49,10 @@ declare_args() {
|
||||
group("fs") {
|
||||
deps = []
|
||||
deps += [ ".:fs_operations" ]
|
||||
if (enable_ohos_kernel_liteos_m_fatfs == true) {
|
||||
if (enable_ohos_kernel_liteos_m_fatfs) {
|
||||
deps += [ "fatfs:fatfs" ]
|
||||
}
|
||||
if (enable_ohos_kernel_liteos_m_littlefs == true) {
|
||||
if (enable_ohos_kernel_liteos_m_littlefs) {
|
||||
deps += [ "littlefs:littlefs" ]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1432,6 +1432,7 @@ int fatfs_format(const char *dev, int sectors, int option)
|
||||
INT32 index;
|
||||
FRESULT res;
|
||||
INT32 ret;
|
||||
MKFS_PARM opt = {0};
|
||||
|
||||
if (dev == NULL) {
|
||||
errno = EFAULT;
|
||||
@@ -1458,7 +1459,9 @@ int fatfs_format(const char *dev, int sectors, int option)
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
res = f_mkfs(dev, option, sectors, g_workBuffer, FF_MAX_SS);
|
||||
opt.n_sect = sectors;
|
||||
opt.fmt = (BYTE)option;
|
||||
res = f_mkfs(dev, &opt, g_workBuffer, FF_MAX_SS);
|
||||
if (res != FR_OK) {
|
||||
errno = FatfsErrno(res);
|
||||
ret = FS_FAILURE;
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
*/
|
||||
#include "fs_operations.h"
|
||||
#include "los_config.h"
|
||||
#ifdef LOSCFG_SUPPORT_FATFS
|
||||
#if (LOSCFG_SUPPORT_FATFS == 1)
|
||||
#include "fatfs.h"
|
||||
#endif
|
||||
#include "dirent.h"
|
||||
@@ -331,7 +331,7 @@ ssize_t read(int fd, void *buf, size_t nbyte)
|
||||
errno = EINVAL;
|
||||
return FS_FAILURE;
|
||||
}
|
||||
if (nbyte > 1024) {
|
||||
if (nbyte > 1024) { /* 1024, max random_size */
|
||||
nbyte = 1024; /* hks_generate_random: random_size must <= 1024 */
|
||||
}
|
||||
struct hks_blob key = {HKS_BLOB_TYPE_RAW, (uint8_t *)buf, nbyte};
|
||||
@@ -347,14 +347,14 @@ ssize_t read(int fd, void *buf, size_t nbyte)
|
||||
return recv(fd, buf, nbyte, 0);
|
||||
}
|
||||
#endif
|
||||
if (g_fs->fsFops == NULL || g_fs->fsFops->Read == NULL) {
|
||||
errno = ENOSYS;
|
||||
return FS_FAILURE;
|
||||
}
|
||||
if (g_fs == NULL) {
|
||||
errno = ENODEV;
|
||||
return FS_FAILURE;
|
||||
}
|
||||
if (g_fs->fsFops == NULL || g_fs->fsFops->Read == NULL) {
|
||||
errno = ENOSYS;
|
||||
return FS_FAILURE;
|
||||
}
|
||||
return g_fs->fsFops->Read(fd, buf, nbyte);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
|
||||
static_library("littlefs") {
|
||||
sources = [
|
||||
"lfs_api.c",
|
||||
"//third_party/littlefs/lfs.c",
|
||||
"//third_party/littlefs/lfs_util.c",
|
||||
"lfs_api.c",
|
||||
]
|
||||
|
||||
include_dirs = [
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
#define _GNU_SOURCE 1
|
||||
#include "lfs_api.h"
|
||||
#include "los_config.h"
|
||||
#include "los_mux.h"
|
||||
#include "los_debug.h"
|
||||
#include "securec.h"
|
||||
|
||||
lfs_t g_lfs;
|
||||
FileDirInfo g_lfsDir[LFS_MAX_OPEN_DIRS] = {0};
|
||||
@@ -39,59 +42,89 @@ FileDirInfo g_lfsDir[LFS_MAX_OPEN_DIRS] = {0};
|
||||
struct FileOpInfo g_fsOp[LOSCFG_LFS_MAX_MOUNT_SIZE] = {0};
|
||||
static LittleFsHandleStruct g_handle[LITTLE_FS_MAX_OPEN_FILES] = {0};
|
||||
struct dirent g_nameValue;
|
||||
static pthread_mutex_t g_FslocalMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static const char *g_littlefsMntName[LOSCFG_LFS_MAX_MOUNT_SIZE] = {"/a","/b","/c"};
|
||||
static const char *g_littlefsMntName[LOSCFG_LFS_MAX_MOUNT_SIZE] = {"/a", "/b", "/c"};
|
||||
#define LFS_MUTEX_UNINIT (-1)
|
||||
static UINT32 g_lfsMutex = LFS_MUTEX_UNINIT;
|
||||
|
||||
static int LfsLock(void)
|
||||
{
|
||||
if (LOS_MuxPend(g_lfsMutex, LOS_WAIT_FOREVER) != LOS_OK) {
|
||||
PRINT_ERR("LfsLock failed!");
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
static void LfsUnlock(void)
|
||||
{
|
||||
(void)LOS_MuxPost(g_lfsMutex);
|
||||
}
|
||||
|
||||
LittleFsHandleStruct *LfsAllocFd(const char *fileName, int *fd)
|
||||
{
|
||||
pthread_mutex_lock(&g_FslocalMutex);
|
||||
for (int i = 0; i < LITTLE_FS_MAX_OPEN_FILES; i++) {
|
||||
if (g_handle[i].useFlag == 0) {
|
||||
*fd = i;
|
||||
g_handle[i].useFlag = 1;
|
||||
g_handle[i].pathName = strdup(fileName);
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
return &(g_handle[i]);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
*fd = INVALID_FD;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void LfsFreeFd(int fd)
|
||||
{
|
||||
g_handle[fd].useFlag = 0;
|
||||
if (g_handle[fd].pathName != NULL) {
|
||||
free((void *)g_handle[fd].pathName);
|
||||
g_handle[fd].pathName = NULL;
|
||||
}
|
||||
|
||||
if (g_handle[fd].lfsHandle != NULL) {
|
||||
g_handle[fd].lfsHandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CheckFileIsOpen(const char *fileName)
|
||||
{
|
||||
pthread_mutex_lock(&g_FslocalMutex);
|
||||
for (int i = 0; i < LITTLE_FS_MAX_OPEN_FILES; i++) {
|
||||
if (g_handle[i].useFlag == 1) {
|
||||
if (strcmp(g_handle[i].pathName, fileName) == 0) {
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL LfsFdIsValid(int fd)
|
||||
{
|
||||
if (fd >= LITTLE_FS_MAX_OPEN_FILES || fd < 0) {
|
||||
return FALSE;
|
||||
}
|
||||
if (g_handle[fd].lfsHandle == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
FileDirInfo *GetFreeDir(const char *dirName)
|
||||
{
|
||||
pthread_mutex_lock(&g_FslocalMutex);
|
||||
for (int i = 0; i < LFS_MAX_OPEN_DIRS; i++) {
|
||||
if (g_lfsDir[i].useFlag == 0) {
|
||||
g_lfsDir[i].useFlag = 1;
|
||||
g_lfsDir[i].dirName = strdup(dirName);
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
return &(g_lfsDir[i]);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void FreeDirInfo(const char *dirName)
|
||||
void FreeDirInfo(const char *dirName)
|
||||
{
|
||||
pthread_mutex_lock(&g_FslocalMutex);
|
||||
for (int i = 0; i < LFS_MAX_OPEN_DIRS; i++) {
|
||||
if (g_lfsDir[i].useFlag == 1 && strcmp(g_lfsDir[i].dirName, dirName) == 0) {
|
||||
g_lfsDir[i].useFlag = 0;
|
||||
@@ -99,70 +132,63 @@ void FreeDirInfo(const char *dirName)
|
||||
free(g_lfsDir[i].dirName);
|
||||
g_lfsDir[i].dirName = NULL;
|
||||
}
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
}
|
||||
|
||||
BOOL CheckDirIsOpen(const char *dirName)
|
||||
{
|
||||
pthread_mutex_lock(&g_FslocalMutex);
|
||||
for (int i = 0; i < LFS_MAX_OPEN_DIRS; i++) {
|
||||
if (g_lfsDir[i].useFlag == 1) {
|
||||
if (strcmp(g_lfsDir[i].dirName, dirName) == 0) {
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int GetFirstLevelPathLen(const char *pathName)
|
||||
{
|
||||
int len = 1;
|
||||
for (int i = 1; i < strlen(pathName) + 1; i++) {
|
||||
if (pathName[i] == '/') {
|
||||
break;
|
||||
}
|
||||
len++;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
BOOL CheckPathIsMounted(const char *pathName, struct FileOpInfo **fileOpInfo)
|
||||
{
|
||||
char tmpName[LITTLEFS_MAX_LFN_LEN] = {0};
|
||||
int mountPathNameLen;
|
||||
int len = strlen(pathName) + 1;
|
||||
int len = GetFirstLevelPathLen(pathName);
|
||||
|
||||
pthread_mutex_lock(&g_FslocalMutex);
|
||||
for (int i = 0; i < LOSCFG_LFS_MAX_MOUNT_SIZE; i++) {
|
||||
if (g_fsOp[i].useFlag == 1) {
|
||||
mountPathNameLen = strlen(g_fsOp[i].dirName);
|
||||
if (len < mountPathNameLen + 1) {
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
(void)strncpy_s(tmpName, LITTLEFS_MAX_LFN_LEN, pathName, mountPathNameLen);
|
||||
tmpName[mountPathNameLen] = '\0';
|
||||
|
||||
(void)strncpy_s(tmpName, LITTLEFS_MAX_LFN_LEN, pathName, len);
|
||||
if (strcmp(tmpName, g_fsOp[i].dirName) == 0) {
|
||||
*fileOpInfo = &(g_fsOp[i]);
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
struct FileOpInfo *AllocMountRes(const char* target, struct FileOps *fileOps)
|
||||
struct FileOpInfo *AllocMountRes(const char* target, const struct FileOps *fileOps)
|
||||
{
|
||||
pthread_mutex_lock(&g_FslocalMutex);
|
||||
for (int i = 0; i < LOSCFG_LFS_MAX_MOUNT_SIZE; i++) {
|
||||
if (g_fsOp[i].useFlag == 0 && strcmp(target, g_littlefsMntName[i]) == 0) {
|
||||
g_fsOp[i].useFlag = 1;
|
||||
g_fsOp[i].fsVops = fileOps;
|
||||
g_fsOp[i].dirName == strdup(target);
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
g_fsOp[i].dirName = strdup(target);
|
||||
return &(g_fsOp[i]);
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -171,27 +197,22 @@ int SetDefaultMountPath(int pathNameIndex, const char* target)
|
||||
if (pathNameIndex >= LOSCFG_LFS_MAX_MOUNT_SIZE) {
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&g_FslocalMutex);
|
||||
|
||||
g_littlefsMntName[pathNameIndex] = strdup(target);
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
return VFS_OK;
|
||||
}
|
||||
|
||||
struct FileOpInfo *GetMountRes(const char *target, int *mountIndex)
|
||||
{
|
||||
pthread_mutex_lock(&g_FslocalMutex);
|
||||
for (int i = 0; i < LOSCFG_LFS_MAX_MOUNT_SIZE; i++) {
|
||||
if (g_fsOp[i].useFlag == 1) {
|
||||
if (g_fsOp[i].dirName && strcmp(target, g_fsOp[i].dirName) == 0) {
|
||||
*mountIndex = i;
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
return &(g_fsOp[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -201,33 +222,28 @@ int FreeMountResByIndex(int mountIndex)
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&g_FslocalMutex);
|
||||
if (g_fsOp[mountIndex].useFlag == 1 && g_fsOp[mountIndex].dirName != NULL) {
|
||||
g_fsOp[mountIndex].useFlag = 0;
|
||||
free(g_fsOp[mountIndex].dirName);
|
||||
g_fsOp[mountIndex].dirName = NULL;
|
||||
}
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
|
||||
return VFS_OK;
|
||||
}
|
||||
|
||||
int FreeMountRes(const char *target)
|
||||
{
|
||||
pthread_mutex_lock(&g_FslocalMutex);
|
||||
for (int i = 0; i < LOSCFG_LFS_MAX_MOUNT_SIZE; i++) {
|
||||
if (g_fsOp[i].useFlag == 1) {
|
||||
if (g_fsOp[i].dirName && strcmp(target, g_fsOp[i].dirName) == 0) {
|
||||
g_fsOp[i].useFlag = 0;
|
||||
free(g_fsOp[i].dirName);
|
||||
g_fsOp[i].dirName = NULL;
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
return VFS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
@@ -268,45 +284,7 @@ static int ConvertFlagToLfsOpenFlag (int oflags)
|
||||
|
||||
static int LittlefsErrno(int result)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
switch (result) {
|
||||
case LFS_ERR_OK:
|
||||
break;
|
||||
case LFS_ERR_NOTDIR:
|
||||
status = ENOTDIR;
|
||||
break;
|
||||
case LFS_ERR_NOENT:
|
||||
status = ENFILE;
|
||||
break;
|
||||
case LFS_ERR_EXIST:
|
||||
status = EEXIST;
|
||||
break;
|
||||
case LFS_ERR_ISDIR:
|
||||
status = EISDIR;
|
||||
break;
|
||||
case LFS_ERR_NOTEMPTY:
|
||||
status = ENOTEMPTY;
|
||||
break;
|
||||
case LFS_ERR_INVAL:
|
||||
status = EINVAL;
|
||||
break;
|
||||
case LFS_ERR_NOSPC:
|
||||
status = ENOSPC;
|
||||
break;
|
||||
case LFS_ERR_IO:
|
||||
status = EIO;
|
||||
break;
|
||||
default:
|
||||
status = result;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
return (result < 0) ? -result : result;
|
||||
}
|
||||
|
||||
const struct MountOps g_lfsMnt = {
|
||||
@@ -337,6 +315,18 @@ int LfsMount(const char *source, const char *target, const char *fileSystemType,
|
||||
int ret;
|
||||
struct FileOpInfo *fileOpInfo = NULL;
|
||||
|
||||
if (g_lfsMutex == LFS_MUTEX_UNINIT) {
|
||||
if (LOS_MuxCreate(&g_lfsMutex) != LOS_OK) {
|
||||
errno = EBUSY;
|
||||
return VFS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (LfsLock() != LOS_OK) {
|
||||
errno = EAGAIN;
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
if (target == NULL || fileSystemType == NULL || data == NULL) {
|
||||
errno = EFAULT;
|
||||
ret = VFS_ERROR;
|
||||
@@ -351,7 +341,7 @@ int LfsMount(const char *source, const char *target, const char *fileSystemType,
|
||||
|
||||
if (CheckPathIsMounted(target, &fileOpInfo)) {
|
||||
errno = EBUSY;
|
||||
ret = VFS_OK;
|
||||
ret = VFS_ERROR;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
@@ -362,7 +352,7 @@ int LfsMount(const char *source, const char *target, const char *fileSystemType,
|
||||
ret = VFS_ERROR;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
|
||||
ret = lfs_mount(&(fileOpInfo->lfsInfo), (struct lfs_config*)data);
|
||||
if (ret != 0) {
|
||||
ret = lfs_format(&(fileOpInfo->lfsInfo), (struct lfs_config*)data);
|
||||
@@ -373,10 +363,11 @@ int LfsMount(const char *source, const char *target, const char *fileSystemType,
|
||||
|
||||
if (ret != 0) {
|
||||
errno = LittlefsErrno(ret);
|
||||
ret = VFS_ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
errout:
|
||||
LfsUnlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -391,18 +382,26 @@ int LfsUmount(const char *target)
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
if (LfsLock() != LOS_OK) {
|
||||
errno = EAGAIN;
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
fileOpInfo = GetMountRes(target, &mountIndex);
|
||||
if (fileOpInfo == NULL) {
|
||||
errno = ENOENT;
|
||||
LfsUnlock();
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
ret = lfs_unmount(&(fileOpInfo->lfsInfo));
|
||||
if (ret != 0) {
|
||||
errno = LittlefsErrno(ret);
|
||||
ret = VFS_ERROR;
|
||||
}
|
||||
|
||||
(void)FreeMountResByIndex(mountIndex);
|
||||
LfsUnlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -416,16 +415,24 @@ int LfsUnlink(const char *fileName)
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
if (LfsLock() != LOS_OK) {
|
||||
errno = EAGAIN;
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
if (CheckPathIsMounted(fileName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
|
||||
errno = EACCES;
|
||||
errno = ENOENT;
|
||||
LfsUnlock();
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
ret = lfs_remove(&(fileOpInfo->lfsInfo), fileName);
|
||||
if (ret != 0) {
|
||||
errno = LittlefsErrno(ret);
|
||||
ret = VFS_ERROR;
|
||||
}
|
||||
|
||||
LfsUnlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -439,16 +446,24 @@ int LfsMkdir(const char *dirName, mode_t mode)
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
if (LfsLock() != LOS_OK) {
|
||||
errno = EAGAIN;
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
if (CheckPathIsMounted(dirName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
|
||||
errno = EACCES;
|
||||
errno = ENOENT;
|
||||
LfsUnlock();
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
ret = lfs_mkdir(&(fileOpInfo->lfsInfo), dirName);
|
||||
if (ret != 0) {
|
||||
errno = LittlefsErrno(ret);
|
||||
ret = VFS_ERROR;
|
||||
}
|
||||
|
||||
LfsUnlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -463,16 +478,24 @@ int LfsRmdir(const char *dirName)
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
if (LfsLock() != LOS_OK) {
|
||||
errno = EAGAIN;
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
if (CheckPathIsMounted(dirName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
|
||||
errno = EACCES;
|
||||
errno = ENOENT;
|
||||
LfsUnlock();
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
ret = lfs_remove(&(fileOpInfo->lfsInfo), dirName);
|
||||
if (ret != 0) {
|
||||
errno = LittlefsErrno(ret);
|
||||
ret = VFS_ERROR;
|
||||
}
|
||||
|
||||
LfsUnlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -483,11 +506,16 @@ DIR *LfsOpendir(const char *dirName)
|
||||
|
||||
if (dirName == NULL) {
|
||||
errno = EFAULT;
|
||||
goto errout;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (LfsLock() != LOS_OK) {
|
||||
errno = EAGAIN;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (CheckPathIsMounted(dirName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
|
||||
errno = EACCES;
|
||||
errno = ENOENT;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
@@ -505,15 +533,18 @@ DIR *LfsOpendir(const char *dirName)
|
||||
ret = lfs_dir_open(&(fileOpInfo->lfsInfo), (lfs_dir_t *)(&(dirInfo->dir)), dirName);
|
||||
|
||||
if (ret != 0) {
|
||||
FreeDirInfo(dirName);
|
||||
errno = LittlefsErrno(ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
dirInfo->lfsHandle = &(fileOpInfo->lfsInfo);
|
||||
|
||||
LfsUnlock();
|
||||
return (DIR *)dirInfo;
|
||||
|
||||
errout:
|
||||
LfsUnlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -525,13 +556,17 @@ struct dirent *LfsReaddir(DIR *dir)
|
||||
FileDirInfo *dirInfo = (FileDirInfo *)dir;
|
||||
|
||||
if (dirInfo == NULL || dirInfo->lfsHandle == NULL) {
|
||||
errno = EFAULT;
|
||||
errno = EBADF;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (LfsLock() != LOS_OK) {
|
||||
errno = EAGAIN;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = lfs_dir_read(dirInfo->lfsHandle, (lfs_dir_t *)(&(dirInfo->dir)), &lfsInfo);
|
||||
if (ret == 0) {
|
||||
pthread_mutex_lock(&g_FslocalMutex);
|
||||
if (ret == TRUE) {
|
||||
(void)strncpy_s(g_nameValue.d_name, sizeof(g_nameValue.d_name), lfsInfo.name, strlen(lfsInfo.name) + 1);
|
||||
if (lfsInfo.type == LFS_TYPE_DIR) {
|
||||
g_nameValue.d_type = DT_DIR;
|
||||
@@ -540,8 +575,7 @@ struct dirent *LfsReaddir(DIR *dir)
|
||||
}
|
||||
|
||||
g_nameValue.d_reclen = lfsInfo.size;
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
|
||||
LfsUnlock();
|
||||
return &g_nameValue;
|
||||
}
|
||||
|
||||
@@ -549,27 +583,35 @@ struct dirent *LfsReaddir(DIR *dir)
|
||||
errno = LittlefsErrno(ret);
|
||||
}
|
||||
|
||||
LfsUnlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int LfsClosedir(const DIR *dir)
|
||||
int LfsClosedir(DIR *dir)
|
||||
{
|
||||
int ret;
|
||||
FileDirInfo *dirInfo = (FileDirInfo *)dir;
|
||||
|
||||
if (dirInfo == NULL || dirInfo->lfsHandle == NULL) {
|
||||
errno = EFAULT;
|
||||
errno = EBADF;
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
if (LfsLock() != LOS_OK) {
|
||||
errno = EAGAIN;
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
ret = lfs_dir_close(dirInfo->lfsHandle, (lfs_dir_t *)(&(dirInfo->dir)));
|
||||
|
||||
FreeDirInfo(dirInfo->dirName);
|
||||
|
||||
if (ret != 0) {
|
||||
errno = LittlefsErrno(ret);
|
||||
ret = VFS_ERROR;
|
||||
}
|
||||
|
||||
LfsUnlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -582,11 +624,16 @@ int LfsOpen(const char *pathName, int openFlag, int mode)
|
||||
|
||||
if (pathName == NULL) {
|
||||
errno = EFAULT;
|
||||
goto errout;
|
||||
return INVALID_FD;
|
||||
}
|
||||
|
||||
if (LfsLock() != LOS_OK) {
|
||||
errno = EAGAIN;
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
if (CheckPathIsMounted(pathName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
|
||||
errno = EACCES;
|
||||
errno = ENOENT;
|
||||
goto errout;
|
||||
}
|
||||
// if file is already open, return invalid fd
|
||||
@@ -604,109 +651,128 @@ int LfsOpen(const char *pathName, int openFlag, int mode)
|
||||
int lfsOpenFlag = ConvertFlagToLfsOpenFlag(openFlag);
|
||||
err = lfs_file_open(&(fileOpInfo->lfsInfo), &(fsHandle->file), pathName, lfsOpenFlag);
|
||||
if (err != 0) {
|
||||
LfsFreeFd(fd);
|
||||
errno = LittlefsErrno(err);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
g_handle[fd].lfsHandle = &(fileOpInfo->lfsInfo);
|
||||
LfsUnlock();
|
||||
return fd;
|
||||
|
||||
errout:
|
||||
return err;
|
||||
LfsUnlock();
|
||||
return INVALID_FD;
|
||||
}
|
||||
|
||||
int LfsRead(int fd, void *buf, unsigned int len)
|
||||
{
|
||||
int ret;
|
||||
if (fd >= LITTLE_FS_MAX_OPEN_FILES || fd < 0 || buf == NULL) {
|
||||
|
||||
if (buf == NULL) {
|
||||
errno = EFAULT;
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
if (g_handle[fd].lfsHandle == NULL) {
|
||||
if (LfsLock() != LOS_OK) {
|
||||
errno = EAGAIN;
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
if (LfsFdIsValid(fd) == FALSE) {
|
||||
errno = EBADF;
|
||||
LfsUnlock();
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
ret = lfs_file_read(g_handle[fd].lfsHandle, &(g_handle[fd].file), buf, len);
|
||||
if (ret != 0) {
|
||||
if (ret < 0) {
|
||||
errno = LittlefsErrno(ret);
|
||||
ret = VFS_ERROR;
|
||||
}
|
||||
LfsUnlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int LfsWrite(int fd, const void *buf, unsigned int len)
|
||||
{
|
||||
int ret;
|
||||
if (fd >= LITTLE_FS_MAX_OPEN_FILES || fd < 0 || buf == NULL) {
|
||||
|
||||
if (buf == NULL) {
|
||||
errno = EFAULT;
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
if (g_handle[fd].lfsHandle == NULL) {
|
||||
if (LfsLock() != LOS_OK) {
|
||||
errno = EAGAIN;
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
if (LfsFdIsValid(fd) == FALSE) {
|
||||
errno = EBADF;
|
||||
LfsUnlock();
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
ret = lfs_file_write(g_handle[fd].lfsHandle, &(g_handle[fd].file), buf, len);
|
||||
if (ret != 0) {
|
||||
if (ret < 0) {
|
||||
errno = LittlefsErrno(ret);
|
||||
ret = VFS_ERROR;
|
||||
}
|
||||
LfsUnlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int LfsSeek(int fd, off_t offset, int whence)
|
||||
off_t LfsSeek(int fd, off_t offset, int whence)
|
||||
{
|
||||
int ret;
|
||||
if (fd >= LITTLE_FS_MAX_OPEN_FILES || fd < 0) {
|
||||
errno = EFAULT;
|
||||
return VFS_ERROR;
|
||||
}
|
||||
off_t ret;
|
||||
|
||||
if (g_handle[fd].lfsHandle == NULL) {
|
||||
if (LfsLock() != LOS_OK) {
|
||||
errno = EAGAIN;
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
if (LfsFdIsValid(fd) == FALSE) {
|
||||
errno = EBADF;
|
||||
LfsUnlock();
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
ret = lfs_file_seek(g_handle[fd].lfsHandle, &(g_handle[fd].file), offset, whence);
|
||||
if (ret != 0) {
|
||||
ret = (off_t)lfs_file_seek(g_handle[fd].lfsHandle, &(g_handle[fd].file), offset, whence);
|
||||
if (ret < 0) {
|
||||
errno = LittlefsErrno(ret);
|
||||
ret = VFS_ERROR;
|
||||
}
|
||||
|
||||
LfsUnlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int LfsClose(int fd)
|
||||
{
|
||||
int ret = VFS_ERROR;
|
||||
int ret;
|
||||
|
||||
if (fd >= LITTLE_FS_MAX_OPEN_FILES || fd < 0) {
|
||||
errno = EFAULT;
|
||||
return ret;
|
||||
}
|
||||
if (LfsLock() != LOS_OK) {
|
||||
errno = EAGAIN;
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
if (g_handle[fd].lfsHandle == NULL) {
|
||||
if (LfsFdIsValid(fd) == FALSE) {
|
||||
errno = EBADF;
|
||||
LfsUnlock();
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&g_FslocalMutex);
|
||||
ret = lfs_file_close(g_handle[fd].lfsHandle, &(g_handle[fd].file));
|
||||
g_handle[fd].useFlag = 0;
|
||||
if (g_handle[fd].pathName != NULL) {
|
||||
free(g_handle[fd].pathName);
|
||||
g_handle[fd].pathName = NULL;
|
||||
}
|
||||
|
||||
if (g_handle[fd].lfsHandle != NULL) {
|
||||
g_handle[fd].lfsHandle = NULL;
|
||||
}
|
||||
pthread_mutex_unlock(&g_FslocalMutex);
|
||||
LfsFreeFd(fd);
|
||||
|
||||
if (ret != 0) {
|
||||
errno = LittlefsErrno(ret);
|
||||
ret = VFS_ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
LfsUnlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int LfsRename(const char *oldName, const char *newName)
|
||||
@@ -719,16 +785,24 @@ int LfsRename(const char *oldName, const char *newName)
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
if (LfsLock() != LOS_OK) {
|
||||
errno = EAGAIN;
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
if (CheckPathIsMounted(oldName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
|
||||
errno = EACCES;
|
||||
errno = ENOENT;
|
||||
LfsUnlock();
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
ret = lfs_rename(&(fileOpInfo->lfsInfo), oldName, newName);
|
||||
if (ret != 0) {
|
||||
errno = LittlefsErrno(ret);
|
||||
ret = VFS_ERROR;
|
||||
}
|
||||
|
||||
LfsUnlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -743,39 +817,53 @@ int LfsStat(const char *path, struct stat *buf)
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
if (LfsLock() != LOS_OK) {
|
||||
errno = EAGAIN;
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
if (CheckPathIsMounted(path, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
|
||||
errno = EACCES;
|
||||
errno = ENOENT;
|
||||
LfsUnlock();
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
ret = lfs_stat(&(fileOpInfo->lfsInfo), path, &info);
|
||||
if (ret == 0) {
|
||||
buf->st_size = info.size;
|
||||
if (info.type == LFS_TYPE_REG) {
|
||||
buf->st_mode = S_IFREG;
|
||||
} else {
|
||||
buf->st_mode = S_IFDIR;
|
||||
}
|
||||
} else {
|
||||
errno = LittlefsErrno(ret);
|
||||
ret = VFS_ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
LfsUnlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int LfsFsync(int fd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (fd >= LITTLE_FS_MAX_OPEN_FILES || fd < 0) {
|
||||
errno = EFAULT;
|
||||
return VFS_ERROR;
|
||||
}
|
||||
if (LfsLock() != LOS_OK) {
|
||||
errno = EAGAIN;
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
if (g_handle[fd].lfsHandle == NULL) {
|
||||
errno = EACCES;
|
||||
if (LfsFdIsValid(fd) == FALSE) {
|
||||
errno = EBADF;
|
||||
LfsUnlock();
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
ret = lfs_file_sync(g_handle[fd].lfsHandle, &(g_handle[fd].file));
|
||||
if (ret != 0) {
|
||||
errno = LittlefsErrno(ret);
|
||||
ret = VFS_ERROR;
|
||||
}
|
||||
LfsUnlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
#include "lfs.h"
|
||||
#include "lfs_util.h"
|
||||
#include "memory.h"
|
||||
#include "pthread.h"
|
||||
|
||||
#define INVALID_FD (-1)
|
||||
|
||||
@@ -65,7 +64,7 @@ typedef struct {
|
||||
|
||||
struct FileOpInfo {
|
||||
uint8_t useFlag;
|
||||
struct FileOps *fsVops;
|
||||
const struct FileOps *fsVops;
|
||||
char *dirName;
|
||||
lfs_t lfsInfo;
|
||||
};
|
||||
@@ -103,11 +102,11 @@ int LfsMkdir(const char *dirName, mode_t mode);
|
||||
int LfsRmdir(const char *dirName);
|
||||
DIR *LfsOpendir(const char *dirName);
|
||||
struct dirent *LfsReaddir(DIR *dir);
|
||||
int LfsClosedir(const DIR *dir);
|
||||
int LfsClosedir(DIR *dir);
|
||||
int LfsOpen(const char *pathName, int openFlag, int mode);
|
||||
int LfsRead(int fd, void *buf, unsigned int len);
|
||||
int LfsWrite(int fd, const void *buf, unsigned int len);
|
||||
int LfsSeek(int fd, off_t offset, int whence);
|
||||
off_t LfsSeek(int fd, off_t offset, int whence);
|
||||
int LfsClose(int fd);
|
||||
int LfsRename(const char *oldName, const char *newName);
|
||||
int LfsStat(const char *path, struct stat *buf);
|
||||
|
||||
52
components/net/lwip-2.1/BUILD.gn
Normal file
52
components/net/lwip-2.1/BUILD.gn
Normal file
@@ -0,0 +1,52 @@
|
||||
# Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
# of conditions and the following disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
# to endorse or promote products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import("//third_party/lwip/lwip.gni")
|
||||
import("lwip_porting.gni")
|
||||
|
||||
config("lwip_depends") {
|
||||
defines = [ "_BSD_SOURCE = 1" ]
|
||||
}
|
||||
|
||||
static_library("lwip") {
|
||||
include_dirs = [
|
||||
"//kernel/liteos_m/kal/posix/include",
|
||||
"//kernel/liteos_m/kernel/arch/include",
|
||||
]
|
||||
|
||||
include_dirs += LWIP_PORTING_INCLUDE_DIRS
|
||||
include_dirs += LWIP_INCLUDE_DIRS
|
||||
|
||||
sources = LWIP_PORTING_FILES + LWIPNOAPPSFILES
|
||||
|
||||
sources -= [ "$LWIPDIR/api/sockets.c" ]
|
||||
|
||||
configs += [ ":lwip_depends" ]
|
||||
|
||||
deps = [ "//kernel/liteos_m/kal/posix" ]
|
||||
}
|
||||
@@ -39,6 +39,27 @@
|
||||
#define NETIFAPI_VAR_ALLOC(name) API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, name, ERR_MEM)
|
||||
#define NETIFAPI_VAR_FREE(name) API_VAR_FREE(MEMP_NETIFAPI_MSG, name)
|
||||
|
||||
#if LWIP_DHCP
|
||||
#include <lwip/dhcp.h>
|
||||
#include <lwip/prot/dhcp.h>
|
||||
|
||||
err_t dhcp_is_bound(struct netif *netif)
|
||||
{
|
||||
struct dhcp *dhcp = NULL;
|
||||
|
||||
LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG);
|
||||
|
||||
dhcp = netif_dhcp_data(netif);
|
||||
LWIP_ERROR("netif->dhcp != NULL", (dhcp != NULL), return ERR_ARG);
|
||||
|
||||
if (dhcp->state == DHCP_STATE_BOUND) {
|
||||
return ERR_OK;
|
||||
} else {
|
||||
return ERR_INPROGRESS;
|
||||
}
|
||||
}
|
||||
#endif /* LWIP_DHCP */
|
||||
|
||||
static struct netif *netif_find_by_name(const char *name)
|
||||
{
|
||||
struct netif *netif = NULL;
|
||||
|
||||
334
components/net/lwip-2.1/enhancement/src/lwip_ifaddrs.c
Normal file
334
components/net/lwip-2.1/enhancement/src/lwip_ifaddrs.c
Normal file
@@ -0,0 +1,334 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#if LWIP_IFADDRS
|
||||
#if (LWIP_IPV4 || LWIP_IPV6) && LWIP_SOCKET
|
||||
#include "ifaddrs.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/tcpip.h"
|
||||
#include "lwip/priv/sockets_priv.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/dhcp.h"
|
||||
|
||||
struct ifaddrs_storage {
|
||||
struct ifaddrs ifa;
|
||||
union {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in s4;
|
||||
#if LWIP_IPV6
|
||||
struct sockaddr_in6 s6;
|
||||
#endif
|
||||
} addr, netmask, dstaddr;
|
||||
char name[IFNAMSIZ];
|
||||
};
|
||||
|
||||
struct getifaddrs_arg {
|
||||
struct ifaddrs **ifap;
|
||||
sys_sem_t cb_completed;
|
||||
int ret;
|
||||
};
|
||||
|
||||
static int tcpip_init_finish = 1;
|
||||
void lwip_freeifaddrs(struct ifaddrs *ifa);
|
||||
static void ifaddrs_add_tail(struct ifaddrs **ifap, struct ifaddrs *ifaddr)
|
||||
{
|
||||
struct ifaddrs *temp = NULL;
|
||||
|
||||
ifaddr->ifa_next = NULL;
|
||||
if (*ifap == NULL) {
|
||||
*ifap = ifaddr;
|
||||
return;
|
||||
}
|
||||
|
||||
for (temp = *ifap; temp->ifa_next != NULL; temp = temp->ifa_next) {
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
temp->ifa_next = ifaddr;
|
||||
}
|
||||
|
||||
static struct ifaddrs_storage *new_ifaddrs_storage(void)
|
||||
{
|
||||
struct ifaddrs *ifaddr = NULL;
|
||||
struct ifaddrs_storage *if_storage = NULL;
|
||||
|
||||
if_storage = (struct ifaddrs_storage *)mem_malloc(sizeof(struct ifaddrs_storage));
|
||||
if (if_storage != NULL) {
|
||||
(void)memset_s((void*)if_storage, sizeof(struct ifaddrs_storage), 0, sizeof(struct ifaddrs_storage));
|
||||
ifaddr = &if_storage->ifa;
|
||||
ifaddr->ifa_name = if_storage->name;
|
||||
ifaddr->ifa_addr = &if_storage->addr.sa;
|
||||
ifaddr->ifa_netmask = &if_storage->netmask.sa;
|
||||
ifaddr->ifa_dstaddr = &if_storage->dstaddr.sa;
|
||||
}
|
||||
|
||||
return if_storage;
|
||||
}
|
||||
|
||||
static int get_ifa_name(struct netif *netif, struct ifaddrs *ifaddr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (netif->link_layer_type == LOOPBACK_IF) {
|
||||
ifaddr->ifa_flags |= IFF_LOOPBACK;
|
||||
ret = snprintf_s(ifaddr->ifa_name, NETIF_NAMESIZE, (NETIF_NAMESIZE - 1), "%.2s", netif->name);
|
||||
} else {
|
||||
ret = snprintf_s(ifaddr->ifa_name, NETIF_NAMESIZE, (NETIF_NAMESIZE - 1), "%s", netif_get_name(netif));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if LWIP_IPV4
|
||||
static int get_ipv4_ifaddr(struct netif *netif, struct ifaddrs *ifaddr)
|
||||
{
|
||||
struct sockaddr_in *addr_in = NULL;
|
||||
|
||||
if (netif->flags & NETIF_FLAG_UP) {
|
||||
ifaddr->ifa_flags |= IFF_UP;
|
||||
}
|
||||
|
||||
if (netif->flags & NETIF_FLAG_ETHARP) {
|
||||
ifaddr->ifa_flags = ifaddr->ifa_flags & ((unsigned int)(~IFF_NOARP));
|
||||
} else {
|
||||
ifaddr->ifa_flags |= IFF_NOARP;
|
||||
}
|
||||
|
||||
if (netif->flags & NETIF_FLAG_BROADCAST) {
|
||||
ifaddr->ifa_flags |= IFF_BROADCAST;
|
||||
}
|
||||
|
||||
#if LWIP_DHCP
|
||||
if (dhcp_supplied_address(netif)) {
|
||||
ifaddr->ifa_flags |= IFF_DYNAMIC;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LWIP_IGMP
|
||||
if (netif->flags & NETIF_FLAG_IGMP) {
|
||||
ifaddr->ifa_flags |= IFF_MULTICAST;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (netif->flags & NETIF_FLAG_LINK_UP) {
|
||||
ifaddr->ifa_flags |= IFF_RUNNING;
|
||||
}
|
||||
|
||||
#if LWIP_HAVE_LOOPIF
|
||||
if (netif->link_layer_type == LOOPBACK_IF) {
|
||||
addr_in = (struct sockaddr_in *)ifaddr->ifa_addr;
|
||||
addr_in->sin_family = AF_INET;
|
||||
addr_in->sin_addr.s_addr = ((ip4_addr_t *)&netif->ip_addr)->addr;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
addr_in = (struct sockaddr_in *)ifaddr->ifa_addr;
|
||||
addr_in->sin_family = AF_INET;
|
||||
addr_in->sin_addr.s_addr = ((ip4_addr_t *)&netif->ip_addr)->addr;
|
||||
|
||||
addr_in = (struct sockaddr_in *)ifaddr->ifa_netmask;
|
||||
addr_in->sin_family = AF_INET;
|
||||
addr_in->sin_addr.s_addr = ((ip4_addr_t *)&netif->netmask)->addr;
|
||||
|
||||
addr_in = (struct sockaddr_in *)ifaddr->ifa_broadaddr;
|
||||
addr_in->sin_family = AF_INET;
|
||||
addr_in->sin_addr.s_addr = (((ip4_addr_t *)&netif->ip_addr)->addr & ((ip4_addr_t *)&netif->netmask)->addr) |
|
||||
~((ip4_addr_t *)&netif->netmask)->addr;
|
||||
}
|
||||
|
||||
return get_ifa_name(netif, ifaddr);
|
||||
}
|
||||
#endif /* LWIP_IPV4 */
|
||||
|
||||
#if LWIP_IPV6
|
||||
/* Stack support to retrieve the below flags for ipv6
|
||||
IFF_UP
|
||||
IFF_MULTICAST
|
||||
IFF_RUNNING
|
||||
IFF_LOOPBACK
|
||||
*/
|
||||
static int get_ipv6_ifaddr(struct netif *netif, struct ifaddrs *ifaddr, int tmp_index)
|
||||
{
|
||||
struct sockaddr_in6 *addr_in6 = NULL;
|
||||
|
||||
/* As of now supports the below falgs only */
|
||||
if (netif->flags & NETIF_FLAG_UP) {
|
||||
ifaddr->ifa_flags |= IFF_UP;
|
||||
}
|
||||
|
||||
#if LWIP_IPV6_MLD
|
||||
if (netif->flags & NETIF_FLAG_MLD6) {
|
||||
ifaddr->ifa_flags |= IFF_MULTICAST;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (netif->flags & NETIF_FLAG_LINK_UP) {
|
||||
ifaddr->ifa_flags |= IFF_RUNNING;
|
||||
}
|
||||
|
||||
addr_in6 = (struct sockaddr_in6 *)ifaddr->ifa_addr;
|
||||
addr_in6->sin6_family = AF_INET6;
|
||||
inet6_addr_from_ip6addr(&addr_in6->sin6_addr, (ip6_addr_t *)&netif->ip6_addr[tmp_index]);
|
||||
|
||||
return get_ifa_name(netif, ifaddr);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void getifaddrs_internal(struct getifaddrs_arg *arg)
|
||||
{
|
||||
struct netif *netif = NULL;
|
||||
struct ifaddrs *ifaddr = NULL;
|
||||
struct ifaddrs_storage *if_storage = NULL;
|
||||
|
||||
#if LWIP_IPV6
|
||||
int n;
|
||||
#endif
|
||||
|
||||
arg->ret = ENOMEM;
|
||||
for (netif = netif_list; netif != NULL; netif = netif->next) {
|
||||
#if LWIP_IPV4
|
||||
if_storage = new_ifaddrs_storage();
|
||||
if (if_storage == NULL) {
|
||||
lwip_freeifaddrs(
|
||||
*(arg->ifap)); /* ifap is assigned to NULL in getifaddrs, so garbage value will not be there */
|
||||
arg->ret = ENOMEM;
|
||||
goto RETURN;
|
||||
}
|
||||
|
||||
/* if get one or more netif info, then getifaddrs return 0(OK) */
|
||||
arg->ret = 0;
|
||||
ifaddr = &if_storage->ifa;
|
||||
(void)get_ipv4_ifaddr(netif, ifaddr);
|
||||
ifaddrs_add_tail(arg->ifap, ifaddr);
|
||||
#endif /* LWIP_IPV4 */
|
||||
#if LWIP_IPV6
|
||||
for (n = 0; n < LWIP_IPV6_NUM_ADDRESSES; n++) {
|
||||
if ((netif->ip6_addr_state[n] & IP6_ADDR_VALID) == 0) {
|
||||
continue;
|
||||
}
|
||||
if_storage = new_ifaddrs_storage();
|
||||
if (if_storage == NULL) {
|
||||
lwip_freeifaddrs(
|
||||
*(arg->ifap)); /* ifap is assigned to NULL in getifaddrs, so garbage value will not be there */
|
||||
arg->ret = ENOMEM;
|
||||
goto RETURN;
|
||||
}
|
||||
|
||||
/* if get one or more netif info, then getifaddrs return 0(OK) */
|
||||
arg->ret = 0;
|
||||
ifaddr = &if_storage->ifa;
|
||||
(void)get_ipv6_ifaddr(netif, ifaddr, n);
|
||||
ifaddrs_add_tail(arg->ifap, ifaddr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
RETURN:
|
||||
#if !LWIP_TCPIP_CORE_LOCKING
|
||||
sys_sem_signal(&arg->cb_completed);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
int lwip_getifaddrs(struct ifaddrs **ifap)
|
||||
{
|
||||
struct getifaddrs_arg arg;
|
||||
|
||||
LWIP_ERROR("lwip_getifaddrs : ifap is NULL", (ifap != NULL), return ERR_ARG);
|
||||
*ifap = NULL;
|
||||
|
||||
if (!tcpip_init_finish) {
|
||||
set_errno(EACCES);
|
||||
return -1;
|
||||
}
|
||||
arg.ret = 0;
|
||||
arg.ifap = ifap;
|
||||
|
||||
#if LWIP_TCPIP_CORE_LOCKING
|
||||
LOCK_TCPIP_CORE();
|
||||
getifaddrs_internal(&arg);
|
||||
UNLOCK_TCPIP_CORE();
|
||||
#else
|
||||
|
||||
if (sys_sem_new(&arg.cb_completed, 0) != ERR_OK) {
|
||||
set_errno(ENOMEM);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tcpip_callback((tcpip_callback_fn)getifaddrs_internal, &arg);
|
||||
(void)sys_arch_sem_wait(&arg.cb_completed, 0);
|
||||
sys_sem_free(&arg.cb_completed);
|
||||
#endif
|
||||
|
||||
if (arg.ret != 0) {
|
||||
set_errno(arg.ret);
|
||||
*ifap = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void freeifaddrs_iteration(struct ifaddrs *ifa)
|
||||
{
|
||||
if (ifa == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ifa->ifa_next != NULL) {
|
||||
freeifaddrs_iteration(ifa->ifa_next);
|
||||
}
|
||||
|
||||
mem_free(ifa);
|
||||
}
|
||||
|
||||
void lwip_freeifaddrs(struct ifaddrs *ifa)
|
||||
{
|
||||
freeifaddrs_iteration(ifa);
|
||||
}
|
||||
|
||||
int getifaddrs(struct ifaddrs **ifap)
|
||||
{
|
||||
return lwip_getifaddrs(ifap);
|
||||
}
|
||||
|
||||
void freeifaddrs(struct ifaddrs *ifa)
|
||||
{
|
||||
lwip_freeifaddrs(ifa);
|
||||
}
|
||||
|
||||
#endif /* (LWIP_IPV4 || LWIP_IPV6) && LWIP_SOCKET */
|
||||
#endif /* LWIP_IFADDRS */
|
||||
45
components/net/lwip-2.1/lwip_porting.gni
Executable file
45
components/net/lwip-2.1/lwip_porting.gni
Executable file
@@ -0,0 +1,45 @@
|
||||
# Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
# of conditions and the following disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
# to endorse or promote products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
import("//kernel/liteos_m/config.gni")
|
||||
LWIP_PORTING_DIR = "//kernel/liteos_m/components/net/lwip-2.1"
|
||||
|
||||
LWIP_PORTING_INCLUDE_DIRS = [ "$LWIP_PORTING_DIR/porting/include" ]
|
||||
|
||||
LWIP_PORTING_FILES = [
|
||||
"$LWIP_PORTING_DIR/porting/src/driverif.c",
|
||||
"$LWIP_PORTING_DIR/porting/src/lwip_init.c",
|
||||
"$LWIP_PORTING_DIR/porting/src/netdb_porting.c",
|
||||
"$LWIP_PORTING_DIR/porting/src/sockets_porting.c",
|
||||
"$LWIP_PORTING_DIR/porting/src/sys_arch.c",
|
||||
"$LWIP_PORTING_DIR/enhancement/src/fixme.c",
|
||||
"$LWIP_PORTING_DIR/enhancement/src/lwip_ifaddrs.c",
|
||||
]
|
||||
|
||||
if (enable_ohos_kernel_liteos_m_shell) {
|
||||
LWIP_PORTING_FILES += [ "$LWIP_PORTING_DIR/porting/src/api_shell.c" ]
|
||||
}
|
||||
@@ -44,7 +44,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "securec.h"
|
||||
#include "memory_pool.h"
|
||||
|
||||
#ifdef htons
|
||||
#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS
|
||||
@@ -94,33 +93,17 @@
|
||||
|
||||
#define LWIP_RAND rand
|
||||
|
||||
extern void HilogPrintf(const char *fmt, ...);
|
||||
|
||||
#ifndef HILOG_INFO
|
||||
#define HILOG_INFO(...)
|
||||
#ifndef HILOG_MODULE_APP
|
||||
#define HILOG_MODULE_APP 0
|
||||
#endif
|
||||
#ifndef LWIP_LOGGER
|
||||
#define LWIP_LOGGER(msg)
|
||||
#endif
|
||||
|
||||
#ifndef HILOG_ERROR
|
||||
#define HILOG_ERROR(...)
|
||||
#endif
|
||||
|
||||
#define LWIP_PLATFORM_DIAG(vars) HilogPrintf vars
|
||||
#define LWIP_PLATFORM_ASSERT(x) do {HILOG_ERROR(HILOG_MODULE_APP, \
|
||||
"Assertion \"%s\" errno %d line %d in %s\n", \
|
||||
x, errno, __LINE__, __FILE__);} while (0)
|
||||
|
||||
#define mem_clib_malloc LWIP_MEM_ALLOC
|
||||
#define mem_clib_free LWIP_MEM_FREE
|
||||
#define mem_clib_calloc LWIP_MEM_CALLOC
|
||||
extern void LwipLogPrintf(const char *fmt, ...);
|
||||
#define LWIP_PLATFORM_DIAG(vars) LwipLogPrintf vars
|
||||
#define LWIP_PLATFORM_ASSERT(x) do { \
|
||||
LWIP_PLATFORM_DIAG(("Assertion \"%s\" failed at line %d in %s\n", x, __LINE__, __FILE__)); \
|
||||
} while (0)
|
||||
|
||||
#define init_waitqueue_head(...)
|
||||
#define poll_check_waiters(...)
|
||||
#define IOCTL_CMD_CASE_HANDLER()
|
||||
|
||||
#define DNS_SERVER_ADDRESS(ipaddr) (ip4_addr_set_u32(ipaddr, ipaddr_addr("114.114.114.114")))
|
||||
#define DNS_SERVER_ADDRESS_SECONDARY(ipaddr) (ip4_addr_set_u32(ipaddr, ipaddr_addr("114.114.115.115")))
|
||||
|
||||
#endif /* _LWIP_PORTING_CC_H_ */
|
||||
|
||||
49
components/net/lwip-2.1/porting/include/lwip/api_shell.h
Normal file
49
components/net/lwip-2.1/porting/include/lwip/api_shell.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef LWIP_API_SHELL_H
|
||||
#define LWIP_API_SHELL_H
|
||||
|
||||
#include "arch/cc.h"
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#if defined (__cplusplus) && __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
u32_t lwip_ifconfig(int argc, const char **argv);
|
||||
u32_t OsShellPing(int argc, const char **argv);
|
||||
LWIP_STATIC int OsPingFunc(u32_t *parg);
|
||||
|
||||
#if defined (__cplusplus) && __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* LWIP_HDR_API_SHELL_H */
|
||||
38
components/net/lwip-2.1/porting/include/lwip/dhcp.h
Normal file
38
components/net/lwip-2.1/porting/include/lwip/dhcp.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LWIP_PORTING_DHCP_H_
|
||||
#define _LWIP_PORTING_DHCP_H_
|
||||
|
||||
#include_next <lwip/dhcp.h>
|
||||
|
||||
err_t dhcp_is_bound(struct netif *netif);
|
||||
|
||||
#endif /* _LWIP_PORTING_DHCP_H_ */
|
||||
@@ -43,9 +43,6 @@
|
||||
(ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
|
||||
|
||||
/* directly map this to the lwip internal functions */
|
||||
#define inet_addr(cp) ipaddr_addr(cp)
|
||||
#define inet_aton(cp, addr) ip4addr_aton(cp, (ip4_addr_t*)addr)
|
||||
#define inet_ntoa(addr) ip4addr_ntoa((const ip4_addr_t*)&(addr))
|
||||
#define inet_ntoa_r(addr, buf, buflen) ip4addr_ntoa_r((const ip4_addr_t*)&(addr), buf, buflen)
|
||||
#endif /* LWIP_IPV4 */
|
||||
#if LWIP_IPV6
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
#define LWIP_NETIF_LOOPBACK 1
|
||||
#define LWIP_POSIX_SOCKETS_IO_NAMES 0
|
||||
#define LWIP_RAW 1
|
||||
#define LWIP_SOCKET_OFFSET FAT_MAX_OPEN_FILES
|
||||
#define LWIP_SOCKET_OFFSET 0
|
||||
#define LWIP_SO_RCVBUF 1
|
||||
#define LWIP_SO_RCVTIMEO 1
|
||||
#define LWIP_SO_SNDTIMEO 1
|
||||
@@ -216,79 +216,15 @@
|
||||
#define LWIP_ENABLE_NET_CAPABILITY 1
|
||||
#define LWIP_ENABLE_CAP_NET_BROADCAST 0
|
||||
|
||||
// Options for GT
|
||||
// Options for liteos_m
|
||||
#undef LWIP_NETIF_PROMISC
|
||||
#define LWIP_NETIF_PROMISC 0
|
||||
|
||||
#undef LWIP_ICMP
|
||||
#define LWIP_ICMP 0
|
||||
|
||||
#undef LWIP_DHCP
|
||||
#define LWIP_DHCP 0
|
||||
|
||||
#undef LWIP_IGMP
|
||||
#define LWIP_IGMP 0
|
||||
#define MEMP_MEM_MALLOC 1
|
||||
|
||||
#undef LWIP_IPV6
|
||||
#define LWIP_IPV6 0
|
||||
|
||||
#undef LWIP_IPV6_DHCP6
|
||||
#define LWIP_IPV6_DHCP6 0
|
||||
|
||||
#undef TCP_SND_BUF
|
||||
#define TCP_SND_BUF (65535 / 3)
|
||||
|
||||
#undef TCP_WND
|
||||
#define TCP_WND ((TCP_SND_BUF * 2) / 3)
|
||||
|
||||
#undef TCP_SND_QUEUELEN
|
||||
#define TCP_SND_QUEUELEN (2 * (TCP_SND_BUF / TCP_MSS))
|
||||
|
||||
#undef MEMP_NUM_NETDB
|
||||
#define MEMP_NUM_NETDB 1
|
||||
|
||||
#undef MEMP_NUM_ARP_QUEUE
|
||||
#define MEMP_NUM_ARP_QUEUE 4
|
||||
|
||||
#undef MEMP_NUM_NETBUF
|
||||
#define MEMP_NUM_NETBUF 12
|
||||
|
||||
#undef MEMP_NUM_NETCONN
|
||||
#define MEMP_NUM_NETCONN 32
|
||||
|
||||
#undef MEMP_NUM_PBUF
|
||||
#define MEMP_NUM_PBUF 0
|
||||
|
||||
#undef PBUF_POOL_SIZE
|
||||
#define PBUF_POOL_SIZE 0
|
||||
|
||||
#undef MEMP_NUM_RAW_PCB
|
||||
#define MEMP_NUM_RAW_PCB 8
|
||||
|
||||
#undef MEMP_NUM_REASSDATA
|
||||
#define MEMP_NUM_REASSDATA 12
|
||||
|
||||
#undef MEMP_NUM_TCPIP_MSG_API
|
||||
#define MEMP_NUM_TCPIP_MSG_API 32
|
||||
|
||||
#undef MEMP_NUM_TCPIP_MSG_INPKT
|
||||
#define MEMP_NUM_TCPIP_MSG_INPKT 32
|
||||
|
||||
#undef MEMP_NUM_TCP_PCB
|
||||
#define MEMP_NUM_TCP_PCB 8
|
||||
|
||||
#undef MEMP_NUM_TCP_PCB_LISTEN
|
||||
#define MEMP_NUM_TCP_PCB_LISTEN 4
|
||||
|
||||
#undef MEMP_NUM_TCP_SEG
|
||||
#define MEMP_NUM_TCP_SEG 64
|
||||
|
||||
#undef MEMP_NUM_UDP_PCB
|
||||
#define MEMP_NUM_UDP_PCB 4
|
||||
|
||||
#undef TCPIP_THREAD_STACKSIZE
|
||||
#define TCPIP_THREAD_STACKSIZE 0x1000
|
||||
|
||||
#undef LWIP_SOCKET_SELECT
|
||||
#define LWIP_SOCKET_SELECT 1
|
||||
|
||||
|
||||
@@ -72,6 +72,8 @@ extern "C" {
|
||||
err_t driverif_init(struct netif *netif);
|
||||
void driverif_input(struct netif *netif, struct pbuf *p);
|
||||
|
||||
#define netif_get_name(netif) ((netif)->full_name)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
#include <limits.h>
|
||||
#include <fcntl.h>
|
||||
#include_next <lwip/sockets.h>
|
||||
#include <fatfs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
613
components/net/lwip-2.1/porting/src/api_shell.c
Normal file
613
components/net/lwip-2.1/porting/src/api_shell.c
Normal file
@@ -0,0 +1,613 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define LWIP_STATIC static
|
||||
#define DHCP_STATE_OFF 0
|
||||
#define LWIP_EXT_POLL_SUPPORT 1
|
||||
|
||||
#include "lwip/api.h"
|
||||
#include "lwip/netdb.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/icmp.h"
|
||||
#include "los_config.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "shcmd.h"
|
||||
#include "shell.h"
|
||||
#include "los_debug.h"
|
||||
#include "los_task.h"
|
||||
|
||||
/* Forward Declarations [START] */
|
||||
#ifndef LWIP_TESTBED
|
||||
LWIP_STATIC
|
||||
#endif
|
||||
int print_netif(struct netif *netif, char *print_buf, unsigned int buf_len);
|
||||
|
||||
#ifndef LWIP_TESTBED
|
||||
LWIP_STATIC
|
||||
#endif
|
||||
void lwip_ifconfig_show_internal(void *arg);
|
||||
|
||||
#if LWIP_DNS
|
||||
LWIP_STATIC unsigned int get_hostip(const char *hname);
|
||||
|
||||
#ifndef LWIP_TESTBED
|
||||
LWIP_STATIC
|
||||
#endif
|
||||
struct hostent *gethostnameinfo(const char *host, char *tmphstbuf, size_t hstbuflen);
|
||||
#endif /* LWIP_DNS */
|
||||
|
||||
#define PRINT_BUF_LEN 1024
|
||||
|
||||
struct ifconfig_option {
|
||||
char iface[IFNAMSIZ];
|
||||
unsigned int option;
|
||||
ip_addr_t ip_addr;
|
||||
ip_addr_t netmask;
|
||||
ip_addr_t gw;
|
||||
unsigned char ethaddr[6];
|
||||
u16_t mtu;
|
||||
/* when using telnet, print to the telnet socket will result in system */
|
||||
/* deadlock. So we cahe the prinf data to a buf, and when the tcpip */
|
||||
/* callback returns, then print the data out to the telnet socket */
|
||||
sys_sem_t cb_completed;
|
||||
char cb_print_buf[PRINT_BUF_LEN];
|
||||
unsigned int print_len;
|
||||
};
|
||||
|
||||
#ifndef LWIP_TESTBED
|
||||
LWIP_STATIC
|
||||
#endif
|
||||
int print_netif(struct netif *netif, char *print_buf, unsigned int buf_len)
|
||||
{
|
||||
int i, ret;
|
||||
char *tmp = print_buf;
|
||||
|
||||
if (buf_len < 1) {
|
||||
goto out;
|
||||
}
|
||||
if (netif->link_layer_type == LOOPBACK_IF) {
|
||||
ret = snprintf_s(tmp, buf_len, (buf_len - 1), "%s\t", netif->name);
|
||||
} else {
|
||||
ret = snprintf_s(tmp, buf_len, (buf_len - 1), "%s%u\t", netif->name, netif->num);
|
||||
}
|
||||
|
||||
if ((ret <= 0) || ((unsigned int)ret >= buf_len))
|
||||
goto out;
|
||||
tmp += ret;
|
||||
buf_len -= (unsigned int)ret;
|
||||
#if LWIP_IPV4
|
||||
ret = snprintf_s(tmp, buf_len, (buf_len - 1), "ip:%s ", ipaddr_ntoa(&netif->ip_addr));
|
||||
if ((ret <= 0) || ((unsigned int)ret >= buf_len))
|
||||
goto out;
|
||||
tmp += ret;
|
||||
buf_len -= (unsigned int)ret;
|
||||
|
||||
ret = snprintf_s(tmp, buf_len, (buf_len - 1), "netmask:%s ", ipaddr_ntoa(&netif->netmask));
|
||||
if ((ret <= 0) || ((unsigned int)ret >= buf_len))
|
||||
goto out;
|
||||
tmp += ret;
|
||||
buf_len -= (unsigned int)ret;
|
||||
|
||||
ret = snprintf_s(tmp, buf_len, (buf_len - 1), "gateway:%s\n", ipaddr_ntoa(&netif->gw));
|
||||
if ((ret <= 0) || ((unsigned int)ret >= buf_len))
|
||||
goto out;
|
||||
tmp += ret;
|
||||
buf_len -= (unsigned int)ret;
|
||||
#endif
|
||||
ret = snprintf_s(tmp, buf_len, (buf_len - 1), "\tHWaddr ");
|
||||
if ((ret <= 0) || ((unsigned int)ret >= buf_len))
|
||||
goto out;
|
||||
tmp += ret;
|
||||
buf_len -= (unsigned int)ret;
|
||||
|
||||
for (i = 0; i < netif->hwaddr_len - 1; i++) {
|
||||
ret = snprintf_s(tmp, buf_len, (buf_len - 1), "%02x:", netif->hwaddr[i]);
|
||||
if ((ret <= 0) || ((unsigned int)ret >= buf_len))
|
||||
goto out;
|
||||
tmp += ret;
|
||||
buf_len -= (unsigned int)ret;
|
||||
}
|
||||
|
||||
ret = snprintf_s(tmp, buf_len, (buf_len - 1), "%02x", netif->hwaddr[i]);
|
||||
if ((ret <= 0) || ((unsigned int)ret >= buf_len))
|
||||
goto out;
|
||||
tmp += ret;
|
||||
buf_len -= (unsigned int)ret;
|
||||
|
||||
ret = snprintf_s(tmp, buf_len, (buf_len - 1), " MTU:%d %s", netif->mtu,
|
||||
netif->flags & NETIF_FLAG_UP ? "Running" : "Stop");
|
||||
if ((ret <= 0) || ((unsigned int)ret >= buf_len))
|
||||
goto out;
|
||||
tmp += ret;
|
||||
buf_len -= (unsigned int)ret;
|
||||
|
||||
if (netif_default == netif && netif_is_up(netif)) {
|
||||
ret = snprintf_s(tmp, buf_len, (buf_len - 1), " %s", "Default");
|
||||
if ((ret <= 0) || ((unsigned int)ret >= buf_len))
|
||||
goto out;
|
||||
tmp += ret;
|
||||
buf_len -= (unsigned int)ret;
|
||||
}
|
||||
|
||||
ret = snprintf_s(tmp, buf_len, (buf_len - 1), " %s\n", netif->flags & NETIF_FLAG_LINK_UP ? "Link UP" : "Link Down");
|
||||
if ((ret <= 0) || ((unsigned int)ret >= buf_len))
|
||||
goto out;
|
||||
tmp += ret;
|
||||
|
||||
out:
|
||||
return (int)(tmp - print_buf);
|
||||
}
|
||||
|
||||
#ifndef LWIP_TESTBED
|
||||
LWIP_STATIC
|
||||
#endif
|
||||
void lwip_ifconfig_show_internal(void *arg)
|
||||
{
|
||||
struct netif *netif = NULL;
|
||||
struct ifconfig_option *ifconfig_cmd = (struct ifconfig_option *)arg;
|
||||
int ret;
|
||||
|
||||
if (netif_list == NULL) {
|
||||
ret = snprintf_s(ifconfig_cmd->cb_print_buf, PRINT_BUF_LEN - ifconfig_cmd->print_len,
|
||||
((PRINT_BUF_LEN - ifconfig_cmd->print_len) - 1), "Device not init\n");
|
||||
if ((ret > 0) && ((unsigned int)ret < (PRINT_BUF_LEN - ifconfig_cmd->print_len))) {
|
||||
ifconfig_cmd->print_len += (unsigned int)ret;
|
||||
}
|
||||
sys_sem_signal(&ifconfig_cmd->cb_completed);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ifconfig_cmd->iface[0] == '\0') {
|
||||
/* display all netif */
|
||||
for (netif = netif_list; netif != NULL; netif = netif->next) {
|
||||
ret = print_netif(netif, ifconfig_cmd->cb_print_buf + ifconfig_cmd->print_len,
|
||||
PRINT_BUF_LEN - ifconfig_cmd->print_len);
|
||||
ifconfig_cmd->print_len += (unsigned int)ret;
|
||||
}
|
||||
} else {
|
||||
netif = netif_find(ifconfig_cmd->iface);
|
||||
if (netif == NULL) {
|
||||
ret = snprintf_s(ifconfig_cmd->cb_print_buf + ifconfig_cmd->print_len,
|
||||
(PRINT_BUF_LEN - ifconfig_cmd->print_len),
|
||||
((PRINT_BUF_LEN - ifconfig_cmd->print_len) - 1), "Device not found\n");
|
||||
if ((ret > 0) && ((unsigned int)ret < (PRINT_BUF_LEN - ifconfig_cmd->print_len))) {
|
||||
ifconfig_cmd->print_len += (unsigned int)ret;
|
||||
}
|
||||
|
||||
sys_sem_signal(&ifconfig_cmd->cb_completed);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = print_netif(netif, ifconfig_cmd->cb_print_buf + ifconfig_cmd->print_len,
|
||||
PRINT_BUF_LEN - ifconfig_cmd->print_len);
|
||||
ifconfig_cmd->print_len += (unsigned int)ret;
|
||||
}
|
||||
sys_sem_signal(&ifconfig_cmd->cb_completed);
|
||||
}
|
||||
|
||||
/*lint -e838 -e438*/
|
||||
u32_t lwip_ifconfig(int argc, const char **argv)
|
||||
{
|
||||
static struct ifconfig_option ifconfig_cmd;
|
||||
err_t ret;
|
||||
|
||||
#if LWIP_STATS
|
||||
u32_t stat_err_cnt;
|
||||
u32_t stat_drop_cnt;
|
||||
u32_t stat_rx_or_tx_cnt;
|
||||
u32_t stat_rx_or_tx_bytes;
|
||||
#endif
|
||||
|
||||
(void)memset_s(&ifconfig_cmd, sizeof(ifconfig_cmd), 0, sizeof(ifconfig_cmd));
|
||||
if (sys_sem_new(&ifconfig_cmd.cb_completed, 0) != ERR_OK) {
|
||||
PRINTK("%s: sys_sem_new fail\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get the interface */
|
||||
|
||||
/* no more arguments, show all the interface state. */
|
||||
ret = tcpip_callback(lwip_ifconfig_show_internal, &ifconfig_cmd);
|
||||
if (ret != ERR_OK) {
|
||||
sys_sem_free(&ifconfig_cmd.cb_completed);
|
||||
PRINTK("ifconfig : internal error, l:%d err:%d\n", __LINE__, ret);
|
||||
return 1;
|
||||
}
|
||||
(void)sys_arch_sem_wait(&ifconfig_cmd.cb_completed, 0);
|
||||
sys_sem_free(&ifconfig_cmd.cb_completed);
|
||||
ifconfig_cmd.cb_print_buf[PRINT_BUF_LEN - 1] = '\0';
|
||||
PRINTK("%s", ifconfig_cmd.cb_print_buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*lint +e838 +e438*/
|
||||
|
||||
#if LWIP_DNS
|
||||
#ifndef LWIP_TESTBED
|
||||
LWIP_STATIC
|
||||
#endif
|
||||
struct hostent *gethostnameinfo(const char *host, char *tmphstbuf, size_t hstbuflen)
|
||||
{
|
||||
static struct hostent hostbuf;
|
||||
struct hostent *hp = NULL;
|
||||
int res;
|
||||
int herr;
|
||||
|
||||
if (tmphstbuf == NULL)
|
||||
return NULL;
|
||||
res = lwip_gethostbyname_r(host, &hostbuf, tmphstbuf, hstbuflen, &hp, &herr);
|
||||
/* Check for errors. */
|
||||
if (res || hp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return hp;
|
||||
}
|
||||
|
||||
LWIP_STATIC unsigned int get_hostip(const char *hname)
|
||||
{
|
||||
unsigned int ip = 0;
|
||||
int ret;
|
||||
const size_t hstbuflen = 1024;
|
||||
char *tmphstbuf = NULL;
|
||||
|
||||
tmphstbuf = (char *)zalloc(sizeof(char) * hstbuflen);
|
||||
if (tmphstbuf == NULL)
|
||||
return 0;
|
||||
|
||||
struct hostent *pent = gethostnameinfo(hname, tmphstbuf, hstbuflen);
|
||||
if (pent == NULL || pent->h_addr == NULL) {
|
||||
free(tmphstbuf);
|
||||
return 0;
|
||||
}
|
||||
ret = memcpy_s(&ip, sizeof(ip), pent->h_addr, 4);
|
||||
if (ret != 0) {
|
||||
free(tmphstbuf);
|
||||
return 0;
|
||||
}
|
||||
free(tmphstbuf);
|
||||
return ip;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int ping_taskid = -1;
|
||||
static int ping_kill = 0;
|
||||
#define LWIP_SHELL_CMD_PING_TIMEOUT 2000
|
||||
#define LWIP_SHELL_CMD_PING_RETRY_TIMES 4
|
||||
#define PING_ZERO_DATA_LEN 8
|
||||
|
||||
static void lwip_ping_usage(void)
|
||||
{
|
||||
PRINTK("Usage:\n ping [ip]\n");
|
||||
}
|
||||
|
||||
LWIP_STATIC int OsPingFunc(u32_t *parg)
|
||||
{
|
||||
int sfd;
|
||||
struct sockaddr_in to;
|
||||
struct pbuf *pbuf_resp = NULL;
|
||||
struct icmp_echo_hdr *iecho = NULL;
|
||||
struct icmp_echo_hdr *iecho_resp = NULL;
|
||||
struct ip_hdr *iphdr_resp = NULL;
|
||||
u32_t iecho_len;
|
||||
s16_t ip_hlen;
|
||||
u32_t forever;
|
||||
u32_t i;
|
||||
u32_t succ_cnt = 0;
|
||||
u32_t failed_cnt = 0;
|
||||
struct timespec start, end;
|
||||
long timout_ms;
|
||||
struct pollfd pfd;
|
||||
long rtt;
|
||||
int ret = 0;
|
||||
u32_t intrvl;
|
||||
char *data_buf = NULL;
|
||||
BOOL timeout_flag = FALSE;
|
||||
char buf[50];
|
||||
|
||||
u32_t destip = parg[0];
|
||||
u32_t cnt = parg[1];
|
||||
u32_t interval = parg[2];
|
||||
u32_t data_len = parg[3];
|
||||
|
||||
iecho_len = sizeof(struct icmp_echo_hdr) + data_len;
|
||||
sfd = lwip_socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
|
||||
if (sfd < 0) {
|
||||
perror("Ping socket");
|
||||
return -1;
|
||||
}
|
||||
pbuf_resp = pbuf_alloc(PBUF_RAW, IP_HLEN + sizeof(struct icmp_echo_hdr), PBUF_RAM);
|
||||
if (pbuf_resp == NULL) {
|
||||
PRINTK("Ping: pbuf_resp malloc failed\n");
|
||||
ret = -1;
|
||||
goto FAILURE;
|
||||
}
|
||||
iecho = (struct icmp_echo_hdr *)mem_malloc(iecho_len);
|
||||
if (iecho == NULL) {
|
||||
PRINTK("Ping: echo request malloc failed\n");
|
||||
ret = -1;
|
||||
goto FAILURE;
|
||||
}
|
||||
|
||||
to.sin_family = AF_INET;
|
||||
to.sin_addr.s_addr = destip; /* already in network order */
|
||||
to.sin_port = 0;
|
||||
|
||||
if (data_len > PING_ZERO_DATA_LEN) {
|
||||
(void)memset_s(iecho, sizeof(struct icmp_echo_hdr) + PING_ZERO_DATA_LEN,
|
||||
0, sizeof(struct icmp_echo_hdr) + PING_ZERO_DATA_LEN);
|
||||
data_buf = (char *)iecho + sizeof(struct icmp_echo_hdr) + PING_ZERO_DATA_LEN;
|
||||
for (i = 0; i < data_len - PING_ZERO_DATA_LEN; i++) {
|
||||
*(data_buf + i) = i + 0x10;
|
||||
}
|
||||
} else {
|
||||
(void)memset_s(iecho, sizeof(struct icmp_echo_hdr) + data_len, 0, sizeof(struct icmp_echo_hdr) + data_len);
|
||||
}
|
||||
iecho->id = htons((u16_t)LOS_CurTaskIDGet());
|
||||
ICMPH_TYPE_SET(iecho, (u8_t)ICMP_ECHO);
|
||||
forever = (cnt ? 0 : 1);
|
||||
i = 0;
|
||||
while (!ping_kill && (forever || (i < cnt))) {
|
||||
iecho->seqno = htons((u16_t)i);
|
||||
iecho->chksum = 0;
|
||||
iecho->chksum = inet_chksum((void *)iecho, iecho_len);
|
||||
|
||||
ret = sendto(sfd, iecho, iecho_len, 0, (struct sockaddr *)&to, (socklen_t)sizeof(to));
|
||||
if (ret < 0) {
|
||||
perror("Ping: sending ICMP echo request failed\n");
|
||||
goto FAILURE;
|
||||
}
|
||||
|
||||
/* capture the start time to calculate RTT */
|
||||
(void)clock_gettime(CLOCK_MONOTONIC_RAW, &start);
|
||||
|
||||
/* poll for ICMP echo response msg */
|
||||
pfd.fd = sfd;
|
||||
|
||||
do {
|
||||
pfd.events = POLLIN;
|
||||
pfd.revents = 0;
|
||||
timeout_flag = FALSE;
|
||||
ret = poll(&pfd, 1, LWIP_SHELL_CMD_PING_TIMEOUT);
|
||||
if (ret < 0) {
|
||||
perror("Ping: poll\n");
|
||||
goto FAILURE;
|
||||
} else if (ret == 0) {
|
||||
/* first type timeout event */
|
||||
timeout_flag = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = recv(sfd, pbuf_resp->payload, pbuf_resp->len, MSG_DONTWAIT);
|
||||
if (ret < 0) {
|
||||
perror("Ping: recv echo reply failed\n");
|
||||
goto FAILURE;
|
||||
}
|
||||
|
||||
/* Accessing ip header and icmp header */
|
||||
iphdr_resp = pbuf_resp->payload;
|
||||
|
||||
ip_hlen = (IPH_HL(iphdr_resp) << 2);
|
||||
if (pbuf_header(pbuf_resp, -ip_hlen)) {
|
||||
/* this failure will never happen, but failure handle is written just to be in safe side */
|
||||
PRINTK("Ping : memory management failure\n");
|
||||
goto FAILURE;
|
||||
}
|
||||
iecho_resp = (struct icmp_echo_hdr *)pbuf_resp->payload;
|
||||
/* Reverting back pbuf to its original state */
|
||||
if (pbuf_header(pbuf_resp, ip_hlen)) {
|
||||
/* this failure will never happen, but failure handle is written just to be in safe side */
|
||||
PRINTK("ping : memory management failure\n");
|
||||
goto FAILURE;
|
||||
}
|
||||
|
||||
if ((iphdr_resp->src.addr != to.sin_addr.s_addr) ||
|
||||
((ICMPH_TYPE(iecho_resp) == ICMP_ECHO) && (iphdr_resp->src.addr == to.sin_addr.s_addr))) {
|
||||
/* second type timeout event */
|
||||
(void)clock_gettime(CLOCK_MONOTONIC_RAW, &end);
|
||||
timout_ms = ((end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000);
|
||||
timout_ms = LWIP_SHELL_CMD_PING_TIMEOUT - timout_ms;
|
||||
} else {
|
||||
timout_ms = 0;
|
||||
break;
|
||||
}
|
||||
} while (timout_ms >= 0);
|
||||
|
||||
/* all timeout events are true timeout */
|
||||
if ((timout_ms < 0) || (timeout_flag == TRUE)) {
|
||||
failed_cnt++;
|
||||
i++;
|
||||
PRINTK("\nPing: destination unreachable ...");
|
||||
continue;
|
||||
}
|
||||
/* capture the end time to calculate round trip time */
|
||||
(void)clock_gettime(CLOCK_MONOTONIC_RAW, &end);
|
||||
rtt = ((end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000);
|
||||
|
||||
if (iphdr_resp->src.addr == to.sin_addr.s_addr) {
|
||||
switch (ICMPH_TYPE(iecho_resp)) {
|
||||
case ICMP_ER:
|
||||
PRINTK("\n[%u]Reply from %s: ", i, inet_ntop(AF_INET, &to.sin_addr, buf, sizeof(buf)));
|
||||
if (rtt > 0) {
|
||||
PRINTK("time=%ims ", rtt);
|
||||
} else {
|
||||
PRINTK("time<1ms ");
|
||||
}
|
||||
PRINTK("TTL=%u", iphdr_resp->_ttl);
|
||||
|
||||
/* delay 1s for every successful ping */
|
||||
intrvl = interval;
|
||||
do {
|
||||
if (intrvl < 1000) {
|
||||
sys_msleep(intrvl);
|
||||
break;
|
||||
}
|
||||
intrvl -= 1000;
|
||||
sys_msleep(1000);
|
||||
if (ping_kill == 1)
|
||||
break;
|
||||
} while (intrvl > 0);
|
||||
succ_cnt++;
|
||||
break;
|
||||
case ICMP_DUR:
|
||||
PRINTK("\nPing: destination host unreachable ...");
|
||||
break;
|
||||
case ICMP_SQ:
|
||||
PRINTK("\nPing: source quench ...");
|
||||
break;
|
||||
case ICMP_RD:
|
||||
PRINTK("\nPing: redirect ...");
|
||||
break;
|
||||
case ICMP_TE:
|
||||
PRINTK("\nPing: time exceeded ...");
|
||||
break;
|
||||
case ICMP_PP:
|
||||
PRINTK("\nPing: parameter problem ...");
|
||||
break;
|
||||
default:
|
||||
PRINTK("\nPing: unknow error ...");
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
PRINTK("\n--- %s ping statistics ---\n", inet_ntop(AF_INET, &to.sin_addr, buf, sizeof(buf)));
|
||||
PRINTK("%u packets transmitted, %u received, %u loss\n", i, succ_cnt, failed_cnt);
|
||||
|
||||
FAILURE:
|
||||
ping_kill = 0;
|
||||
(void)lwip_close(sfd);
|
||||
if (pbuf_resp != NULL) {
|
||||
(void)pbuf_free(pbuf_resp);
|
||||
}
|
||||
if (iecho != NULL) {
|
||||
mem_free(iecho);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ping_cmd(u32_t *parg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = OsPingFunc(parg);
|
||||
if (ret < 0) {
|
||||
PRINTK("Ping cmd failed due to some errors\n");
|
||||
}
|
||||
|
||||
ping_taskid = -1;
|
||||
}
|
||||
|
||||
u32_t OsShellPing(int argc, const char **argv)
|
||||
{
|
||||
int ret;
|
||||
u32_t i = 0;
|
||||
u32_t count = 0;
|
||||
int count_set = 0;
|
||||
u32_t interval = 1000; /* default ping interval */
|
||||
u32_t data_len = 48; /* default data length */
|
||||
ip4_addr_t dst_ipaddr;
|
||||
TSK_INIT_PARAM_S stPingTask;
|
||||
u32_t *parg = NULL;
|
||||
|
||||
if ((argc < 1) || (argv == NULL)) {
|
||||
PRINTK("Ping: require dest ipaddr at least\n");
|
||||
goto ping_error;
|
||||
}
|
||||
|
||||
if (!count_set) {
|
||||
count = LWIP_SHELL_CMD_PING_RETRY_TIMES;
|
||||
}
|
||||
|
||||
/* initialize dst IP address */
|
||||
if (argc <= 0) {
|
||||
goto ping_error;
|
||||
}
|
||||
#if LWIP_DNS
|
||||
dst_ipaddr.addr = get_hostip(argv[i]);
|
||||
#endif /* LWIP_DNS */
|
||||
|
||||
if (dst_ipaddr.addr == IPADDR_NONE || dst_ipaddr.addr == IPADDR_ANY) {
|
||||
PRINTK("Invalid dest ipaddr: NONE or ANY\n");
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
parg = (u32_t *)malloc(4 * sizeof(int));
|
||||
if (parg == NULL) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
parg[0] = dst_ipaddr.addr;
|
||||
parg[1] = count;
|
||||
parg[2] = interval;
|
||||
parg[3] = data_len;
|
||||
|
||||
/* start one task if ping forever or ping count greater than 60 */
|
||||
if (count == 0 || count > LWIP_SHELL_CMD_PING_RETRY_TIMES) {
|
||||
if (ping_taskid > 0) {
|
||||
free(parg);
|
||||
PRINTK("Ping task already running and only support one now\n");
|
||||
return LOS_NOK;
|
||||
}
|
||||
stPingTask.pfnTaskEntry = (TSK_ENTRY_FUNC)ping_cmd;
|
||||
stPingTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
|
||||
stPingTask.pcName = "ping_task";
|
||||
stPingTask.usTaskPrio = 8; /* higher than shell */
|
||||
stPingTask.uwResved = LOS_TASK_STATUS_DETACHED;
|
||||
stPingTask.uwArg = (UINTPTR)parg;
|
||||
ret = LOS_TaskCreate((UINT32 *)(&ping_taskid), &stPingTask);
|
||||
if (ret != LOS_OK) {
|
||||
PRINTK("ping_task create failed 0x%08x.\n", ret);
|
||||
count = LWIP_SHELL_CMD_PING_RETRY_TIMES;
|
||||
} else {
|
||||
return LOS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* two cases:
|
||||
1, ping cout less than LWIP_SHELL_CMD_PING_RETRY_TIMES;
|
||||
2, ping task create failed;
|
||||
*/
|
||||
if (OsPingFunc(parg) < 0) {
|
||||
PRINTK("Ping cmd failed due some errors\n");
|
||||
}
|
||||
|
||||
free(parg);
|
||||
|
||||
return LOS_OK;
|
||||
ping_error:
|
||||
lwip_ping_usage();
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
@@ -31,10 +31,31 @@
|
||||
|
||||
#include "lwip/netdb.h"
|
||||
|
||||
#if LWIP_DNS && LWIP_SOCKET
|
||||
|
||||
struct hostent *gethostbyname(const char *name)
|
||||
{
|
||||
if (name == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return lwip_gethostbyname(name);
|
||||
}
|
||||
}
|
||||
|
||||
int gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result,
|
||||
int *h_errnop)
|
||||
{
|
||||
return lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop);
|
||||
}
|
||||
|
||||
void freeaddrinfo(struct addrinfo *res)
|
||||
{
|
||||
lwip_freeaddrinfo(res);
|
||||
}
|
||||
|
||||
int getaddrinfo(const char *restrict nodename, const char *restrict servname, const struct addrinfo *restrict hints,
|
||||
struct addrinfo **restrict res)
|
||||
{
|
||||
return lwip_getaddrinfo(nodename, servname, hints, res);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -29,10 +29,12 @@
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "lwip/sockets.h"
|
||||
#include "lwip/priv/tcpip_priv.h"
|
||||
#include "lwip/priv/sockets_priv.h"
|
||||
#include <lwip/sockets.h>
|
||||
|
||||
#if !LWIP_COMPAT_SOCKETS
|
||||
#if LWIP_SOCKET
|
||||
|
||||
#define CHECK_NULL_PTR(ptr) do { if ((ptr) == NULL) { set_errno(EFAULT); return -1; } } while (0)
|
||||
|
||||
@@ -159,6 +161,27 @@ int inet_pton(int af, const char *src, void *dst)
|
||||
return lwip_inet_pton(af, src, dst);
|
||||
}
|
||||
|
||||
#ifndef LWIP_INET_ADDR_FUNC
|
||||
in_addr_t inet_addr(const char *cp)
|
||||
{
|
||||
return ipaddr_addr(cp);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef LWIP_INET_NTOA_FUNC
|
||||
char *inet_ntoa(struct in_addr addr)
|
||||
{
|
||||
return ip4addr_ntoa((const ip4_addr_t*)&(addr));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef LWIP_INET_ATON_FUNC
|
||||
int inet_aton(const char *cp, struct in_addr *addr)
|
||||
{
|
||||
return ip4addr_aton(cp, (ip4_addr_t*)addr);
|
||||
}
|
||||
#endif
|
||||
|
||||
int ioctlsocket(int s, long cmd, void *argp)
|
||||
{
|
||||
return lwip_ioctl(s, cmd, argp);
|
||||
@@ -178,4 +201,87 @@ int poll(struct pollfd *fds, nfds_t nfds, int timeout)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !LWIP_COMPAT_SOCKETS */
|
||||
unsigned int if_nametoindex(const char *ifname)
|
||||
{
|
||||
return lwip_if_nametoindex(ifname);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* !LWIP_COMPAT_SOCKETS */
|
||||
|
||||
#define IOCTL_CMD_CASE_HANDLER() do { \
|
||||
err_t err; \
|
||||
struct lwip_ioctl_apimsg msg; \
|
||||
msg.sock = sock; \
|
||||
msg.cmd = cmd; \
|
||||
msg.argp = argp; \
|
||||
\
|
||||
err = tcpip_api_call(lwip_do_ioctl_impl, &msg.call); \
|
||||
if (err != ENOSYS) { \
|
||||
sock_set_errno(sock, err); \
|
||||
done_socket(sock); \
|
||||
return -(err != ERR_OK); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
struct lwip_ioctl_apimsg {
|
||||
struct tcpip_api_call_data call;
|
||||
struct lwip_sock *sock;
|
||||
long cmd;
|
||||
void *argp;
|
||||
};
|
||||
|
||||
static err_t lwip_do_ioctl_impl(struct tcpip_api_call_data *call);
|
||||
|
||||
#include "../api/sockets.c"
|
||||
|
||||
static u8_t lwip_ioctl_internal_SIOCGIFBRDADDR(struct ifreq *ifr)
|
||||
{
|
||||
struct netif *netif = NULL;
|
||||
struct sockaddr_in *sock_in = NULL;
|
||||
|
||||
/* get netif subnet broadcast addr */
|
||||
netif = netif_find(ifr->ifr_name);
|
||||
if (netif == NULL) {
|
||||
return ENODEV;
|
||||
}
|
||||
if (ip4_addr_isany_val(*(ip_2_ip4(&netif->netmask)))) {
|
||||
return ENXIO;
|
||||
}
|
||||
sock_in = (struct sockaddr_in *)&ifr->ifr_addr;
|
||||
sock_in->sin_family = AF_INET;
|
||||
sock_in->sin_addr.s_addr = (ip_2_ip4(&((netif)->ip_addr))->addr | ~(ip_2_ip4(&netif->netmask)->addr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8_t lwip_ioctl_impl(const struct lwip_sock *sock, long cmd, void *argp)
|
||||
{
|
||||
u8_t err = 0;
|
||||
struct ifreq *ifr = (struct ifreq *)argp;
|
||||
bool is_ipv6 = 0;
|
||||
|
||||
/* allow it only on IPv6 sockets... */
|
||||
is_ipv6 = NETCONNTYPE_ISIPV6((unsigned int)(sock->conn->type));
|
||||
|
||||
switch ((u32_t)cmd) {
|
||||
case SIOCGIFBRDADDR:
|
||||
if (is_ipv6 != 0) {
|
||||
err = EINVAL;
|
||||
} else {
|
||||
err = lwip_ioctl_internal_SIOCGIFBRDADDR(ifr);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
err = ENOSYS;
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(UNIMPL: 0x%lx)\n", cmd));
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static err_t lwip_do_ioctl_impl(struct tcpip_api_call_data *call)
|
||||
{
|
||||
struct lwip_ioctl_apimsg *msg = (struct lwip_ioctl_apimsg *)(void *)call;
|
||||
return lwip_ioctl_impl(msg->sock, msg->cmd, msg->argp);
|
||||
}
|
||||
@@ -180,7 +180,10 @@ err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
|
||||
return ERR_ARG;
|
||||
}
|
||||
|
||||
err_t sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg);
|
||||
err_t sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg)
|
||||
{
|
||||
return ERR_ARG;
|
||||
}
|
||||
|
||||
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeoutMs)
|
||||
{
|
||||
@@ -321,7 +324,7 @@ void sys_mutex_set_invalid(sys_mutex_t *mutex)
|
||||
*mutex = LOSCFG_BASE_IPC_MUX_LIMIT;
|
||||
}
|
||||
|
||||
void HilogPrintf(const char *fmt, ...)
|
||||
void LwipLogPrintf(const char *fmt, ...)
|
||||
{
|
||||
if ((fmt == NULL) || (strlen(fmt) == 0)) {
|
||||
return;
|
||||
@@ -334,8 +337,8 @@ void HilogPrintf(const char *fmt, ...)
|
||||
len = vsprintf_s(buf, sizeof(buf) - 1, fmt, ap);
|
||||
va_end(ap);
|
||||
if (len < 0) {
|
||||
HILOG_INFO(HILOG_MODULE_APP, "log param invalid or buf is not enough.");
|
||||
LWIP_LOGGER("log param invalid or buf is not enough.");
|
||||
return;
|
||||
}
|
||||
HILOG_INFO(HILOG_MODULE_APP, buf);
|
||||
LWIP_LOGGER(buf);
|
||||
}
|
||||
|
||||
36
components/power/BUILD.gn
Normal file
36
components/power/BUILD.gn
Normal file
@@ -0,0 +1,36 @@
|
||||
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
# of conditions and the following disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
# to endorse or promote products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import("//kernel/liteos_m/config.gni")
|
||||
|
||||
static_library("pm") {
|
||||
sources = [ "los_pm.c" ]
|
||||
|
||||
configs += [ "$LITEOSTOPDIR:los_config" ]
|
||||
}
|
||||
803
components/power/los_pm.c
Normal file
803
components/power/los_pm.c
Normal file
@@ -0,0 +1,803 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_pm.h"
|
||||
#include "securec.h"
|
||||
#include "los_sched.h"
|
||||
#include "los_timer.h"
|
||||
#include "los_memory.h"
|
||||
#include "los_swtmr.h"
|
||||
|
||||
#if (LOSCFG_KERNEL_PM == 1)
|
||||
#define OS_PM_NODE_FREE 0x80000000U
|
||||
#define OS_PM_LOCK_MAX 0xFFFFU
|
||||
#define OS_PM_SYS_EARLY 1
|
||||
#define OS_PM_SYS_DEVICE_EARLY 2
|
||||
|
||||
typedef UINT32 (*Suspend)(UINT32 mode);
|
||||
|
||||
typedef struct {
|
||||
CHAR *name;
|
||||
UINT32 count;
|
||||
UINT32 swtmrID;
|
||||
LOS_DL_LIST list;
|
||||
} OsPmLockCB;
|
||||
|
||||
typedef struct {
|
||||
LOS_SysSleepEnum pmMode;
|
||||
LOS_SysSleepEnum sysMode;
|
||||
UINT16 lock;
|
||||
BOOL isWake;
|
||||
LosPmDevice *device;
|
||||
LosPmSysctrl *sysctrl;
|
||||
LosPmTickTimer *tickTimer;
|
||||
#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
|
||||
UINT64 enterSleepTime;
|
||||
#endif
|
||||
LOS_DL_LIST lockList;
|
||||
} LosPmCB;
|
||||
|
||||
#define PM_EVENT_LOCK_MASK 0xF
|
||||
#define PM_EVENT_LOCK_RELEASE 0x1
|
||||
STATIC EVENT_CB_S g_pmEvent;
|
||||
STATIC LosPmCB g_pmCB;
|
||||
STATIC LosPmSysctrl g_sysctrl;
|
||||
STATIC UINT64 g_pmSleepTime;
|
||||
|
||||
STATIC VOID OsPmSysctrlInit(VOID)
|
||||
{
|
||||
/* Default handler functions, which are implemented by the product */
|
||||
g_sysctrl.early = NULL;
|
||||
g_sysctrl.late = NULL;
|
||||
g_sysctrl.normalSuspend = HalEnterSleep;
|
||||
g_sysctrl.normalResume = NULL;
|
||||
g_sysctrl.lightSuspend = HalEnterSleep;
|
||||
g_sysctrl.lightResume = NULL;
|
||||
g_sysctrl.deepSuspend = HalEnterSleep;
|
||||
g_sysctrl.deepResume = NULL;
|
||||
g_sysctrl.shutdownSuspend = NULL;
|
||||
g_sysctrl.shutdownResume = NULL;
|
||||
}
|
||||
|
||||
STATIC VOID OsPmTickTimerStart(LosPmCB *pm)
|
||||
{
|
||||
#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
|
||||
UINT64 currTime, sleepTime, realSleepTime;
|
||||
#endif
|
||||
LosPmTickTimer *tickTimer = pm->tickTimer;
|
||||
|
||||
if ((tickTimer == NULL) || (tickTimer->tickUnlock == NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
|
||||
if (tickTimer->timerStop != NULL) {
|
||||
/* Restore the main CPU frequency */
|
||||
sleepTime = tickTimer->timerCycleGet();
|
||||
tickTimer->timerStop();
|
||||
|
||||
realSleepTime = OS_SYS_CYCLE_TO_NS(sleepTime, tickTimer->freq);
|
||||
realSleepTime = OS_SYS_NS_TO_CYCLE(realSleepTime, OS_SYS_CLOCK);
|
||||
currTime = pm->enterSleepTime + realSleepTime;
|
||||
pm->enterSleepTime = 0;
|
||||
|
||||
OsSchedTimerBaseReset(currTime);
|
||||
}
|
||||
#endif
|
||||
|
||||
tickTimer->tickUnlock();
|
||||
return;
|
||||
}
|
||||
|
||||
STATIC BOOL OsPmTickTimerStop(LosPmCB *pm)
|
||||
{
|
||||
#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
|
||||
UINT64 sleepCycle;
|
||||
UINT64 realSleepTime = g_pmSleepTime;
|
||||
#endif
|
||||
LosPmTickTimer *tickTimer = pm->tickTimer;
|
||||
|
||||
if ((tickTimer == NULL) || (tickTimer->tickLock == NULL)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
|
||||
if (tickTimer->timerStart != NULL) {
|
||||
if (realSleepTime == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sleepCycle = OS_SYS_CYCLE_TO_NS(realSleepTime, OS_SYS_CLOCK);
|
||||
sleepCycle = OS_SYS_NS_TO_CYCLE(sleepCycle, tickTimer->freq);
|
||||
|
||||
/* The main CPU reduces the frequency */
|
||||
pm->enterSleepTime = OsGetCurrSysTimeCycle();
|
||||
tickTimer->tickLock();
|
||||
tickTimer->timerStart(sleepCycle);
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
tickTimer->tickLock();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
STATIC VOID OsPmCpuResume(LosPmCB *pm)
|
||||
{
|
||||
if ((pm->sysMode == LOS_SYS_NORMAL_SLEEP) && (pm->sysctrl->normalResume != NULL)) {
|
||||
pm->sysctrl->normalResume();
|
||||
} else if ((pm->sysMode == LOS_SYS_LIGHT_SLEEP) && (pm->sysctrl->lightResume != NULL)) {
|
||||
pm->sysctrl->lightResume();
|
||||
} else if ((pm->sysMode == LOS_SYS_DEEP_SLEEP) && (pm->sysctrl->deepResume != NULL)) {
|
||||
pm->sysctrl->deepResume();
|
||||
}
|
||||
}
|
||||
|
||||
STATIC VOID OsPmCpuSuspend(LosPmCB *pm)
|
||||
{
|
||||
/* cpu enter low power mode */
|
||||
LOS_ASSERT(pm->sysctrl != NULL);
|
||||
|
||||
if (pm->sysMode == LOS_SYS_NORMAL_SLEEP) {
|
||||
pm->sysctrl->normalSuspend();
|
||||
} else if (pm->sysMode == LOS_SYS_LIGHT_SLEEP) {
|
||||
pm->sysctrl->lightSuspend();
|
||||
} else if (pm->sysMode == LOS_SYS_DEEP_SLEEP) {
|
||||
pm->sysctrl->deepSuspend();
|
||||
} else {
|
||||
pm->sysctrl->shutdownSuspend();
|
||||
}
|
||||
}
|
||||
|
||||
STATIC VOID OsPmResumePrepare(LosPmCB *pm, UINT32 mode, UINT32 prepare)
|
||||
{
|
||||
if ((prepare == 0) && (pm->device->resume != NULL)) {
|
||||
pm->device->resume(mode);
|
||||
}
|
||||
|
||||
if (((prepare == 0) || (prepare == OS_PM_SYS_DEVICE_EARLY)) && (pm->sysctrl->late != NULL)) {
|
||||
pm->sysctrl->late(mode);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC UINT32 OsPmSuspendPrepare(Suspend sysSuspendEarly, Suspend deviceSuspend, UINT32 mode, UINT32 *prepare)
|
||||
{
|
||||
UINT32 ret;
|
||||
|
||||
if (sysSuspendEarly != NULL) {
|
||||
ret = sysSuspendEarly(mode);
|
||||
if (ret != LOS_OK) {
|
||||
*prepare = OS_PM_SYS_EARLY;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (deviceSuspend != NULL) {
|
||||
ret = deviceSuspend(mode);
|
||||
if (ret != LOS_OK) {
|
||||
*prepare = OS_PM_SYS_DEVICE_EARLY;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC UINT32 OsPmSuspendCheck(LosPmCB *pm, Suspend *sysSuspendEarly, Suspend *deviceSuspend, LOS_SysSleepEnum *mode)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
pm->sysMode = pm->pmMode;
|
||||
if (pm->lock > 0) {
|
||||
pm->sysMode = LOS_SYS_NORMAL_SLEEP;
|
||||
LOS_IntRestore(intSave);
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
pm->isWake = FALSE;
|
||||
*mode = pm->sysMode;
|
||||
*sysSuspendEarly = pm->sysctrl->early;
|
||||
*deviceSuspend = pm->device->suspend;
|
||||
LOS_IntRestore(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC UINT32 OsPmSuspendSleep(LosPmCB *pm)
|
||||
{
|
||||
UINT32 ret, intSave;
|
||||
Suspend sysSuspendEarly, deviceSuspend;
|
||||
LOS_SysSleepEnum mode;
|
||||
UINT32 prepare = 0;
|
||||
BOOL tickTimerStop = FALSE;
|
||||
UINT64 currTime;
|
||||
|
||||
ret = OsPmSuspendCheck(pm, &sysSuspendEarly, &deviceSuspend, &mode);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = OsPmSuspendPrepare(sysSuspendEarly, deviceSuspend, (UINT32)mode, &prepare);
|
||||
if (ret != LOS_OK) {
|
||||
intSave = LOS_IntLock();
|
||||
LOS_TaskLock();
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
LOS_TaskLock();
|
||||
if (pm->isWake || (pm->lock > 0)) {
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
tickTimerStop = OsPmTickTimerStop(pm);
|
||||
if (!tickTimerStop) {
|
||||
currTime = OsGetCurrSchedTimeCycle();
|
||||
OsSchedResetSchedResponseTime(0);
|
||||
OsSchedUpdateExpireTime(currTime, TRUE);
|
||||
}
|
||||
|
||||
OsPmCpuSuspend(pm);
|
||||
|
||||
OsPmCpuResume(pm);
|
||||
|
||||
OsPmTickTimerStart(pm);
|
||||
|
||||
EXIT:
|
||||
pm->sysMode = LOS_SYS_NORMAL_SLEEP;
|
||||
OsPmResumePrepare(pm, (UINT32)mode, prepare);
|
||||
LOS_IntRestore(intSave);
|
||||
|
||||
LOS_TaskUnlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATIC VOID OsPmNormalSleep(VOID)
|
||||
{
|
||||
UINT32 intSave;
|
||||
LosPmCB *pm = &g_pmCB;
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
|
||||
OsPmCpuSuspend(pm);
|
||||
|
||||
OsPmCpuResume(pm);
|
||||
|
||||
LOS_IntRestore(intSave);
|
||||
}
|
||||
|
||||
STATIC UINT32 OsPmDeviceRegister(LosPmCB *pm, LosPmDevice *device)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
if ((device->suspend == NULL) || (device->resume == NULL)) {
|
||||
return LOS_ERRNO_PM_INVALID_PARAM;
|
||||
}
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
pm->device = device;
|
||||
LOS_IntRestore(intSave);
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC UINT32 OsPmTickTimerRegister(LosPmCB *pm, LosPmTickTimer *tickTimer)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
if ((tickTimer->tickLock == NULL) || (tickTimer->tickUnlock == NULL)) {
|
||||
return LOS_ERRNO_PM_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (((tickTimer->timerStart == NULL) && (tickTimer->timerStop == NULL) &&
|
||||
(tickTimer->timerCycleGet == NULL) && (tickTimer->freq == 0)) ||
|
||||
((tickTimer->timerStart != NULL) && (tickTimer->timerStop != NULL) &&
|
||||
(tickTimer->timerCycleGet != NULL) && (tickTimer->freq != 0))) {
|
||||
intSave = LOS_IntLock();
|
||||
#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
|
||||
pm->enterSleepTime = 0;
|
||||
#endif
|
||||
pm->tickTimer = tickTimer;
|
||||
LOS_IntRestore(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
return LOS_ERRNO_PM_INVALID_PARAM;
|
||||
}
|
||||
|
||||
STATIC UINT32 OsPmSysctrlRegister(LosPmCB *pm, LosPmSysctrl *sysctrl)
|
||||
{
|
||||
UINT32 intSave = LOS_IntLock();
|
||||
if (sysctrl->early != NULL) {
|
||||
pm->sysctrl->early = sysctrl->early;
|
||||
}
|
||||
if (sysctrl->late != NULL) {
|
||||
pm->sysctrl->late = sysctrl->late;
|
||||
}
|
||||
if (sysctrl->normalSuspend != NULL) {
|
||||
pm->sysctrl->normalSuspend = sysctrl->normalSuspend;
|
||||
}
|
||||
if (sysctrl->normalResume != NULL) {
|
||||
pm->sysctrl->normalResume = sysctrl->normalResume;
|
||||
}
|
||||
if (sysctrl->lightSuspend != NULL) {
|
||||
pm->sysctrl->lightSuspend = sysctrl->lightSuspend;
|
||||
}
|
||||
if (sysctrl->lightResume != NULL) {
|
||||
pm->sysctrl->lightResume = sysctrl->lightResume;
|
||||
}
|
||||
if (sysctrl->deepSuspend != NULL) {
|
||||
pm->sysctrl->deepSuspend = sysctrl->deepSuspend;
|
||||
}
|
||||
if (sysctrl->deepResume != NULL) {
|
||||
pm->sysctrl->deepResume = sysctrl->deepResume;
|
||||
}
|
||||
if (sysctrl->shutdownSuspend != NULL) {
|
||||
pm->sysctrl->shutdownSuspend = sysctrl->shutdownSuspend;
|
||||
}
|
||||
if (sysctrl->shutdownResume != NULL) {
|
||||
pm->sysctrl->shutdownResume = sysctrl->shutdownResume;
|
||||
}
|
||||
LOS_IntRestore(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
UINT32 LOS_PmRegister(LOS_PmNodeType type, VOID *node)
|
||||
{
|
||||
LosPmCB *pm = &g_pmCB;
|
||||
|
||||
if (node == NULL) {
|
||||
return LOS_ERRNO_PM_INVALID_PARAM;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case LOS_PM_TYPE_DEVICE:
|
||||
return OsPmDeviceRegister(pm, (LosPmDevice *)node);
|
||||
case LOS_PM_TYPE_TICK_TIMER:
|
||||
return OsPmTickTimerRegister(pm, (LosPmTickTimer *)node);
|
||||
case LOS_PM_TYPE_SYSCTRL:
|
||||
return OsPmSysctrlRegister(pm, (LosPmSysctrl *)node);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return LOS_ERRNO_PM_INVALID_TYPE;
|
||||
}
|
||||
|
||||
STATIC UINT32 OsPmDeviceUnregister(LosPmCB *pm, LosPmDevice *device)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
if (pm->device == device) {
|
||||
pm->device = NULL;
|
||||
pm->pmMode = LOS_SYS_NORMAL_SLEEP;
|
||||
LOS_IntRestore(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LOS_IntRestore(intSave);
|
||||
return LOS_ERRNO_PM_INVALID_NODE;
|
||||
}
|
||||
|
||||
STATIC UINT32 OsPmTickTimerUnregister(LosPmCB *pm, LosPmTickTimer *tickTimer)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
if (pm->tickTimer == tickTimer) {
|
||||
pm->tickTimer = NULL;
|
||||
if ((pm->pmMode != LOS_SYS_NORMAL_SLEEP) && (pm->pmMode != LOS_SYS_LIGHT_SLEEP)) {
|
||||
pm->pmMode = LOS_SYS_NORMAL_SLEEP;
|
||||
}
|
||||
LOS_IntRestore(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LOS_IntRestore(intSave);
|
||||
return LOS_ERRNO_PM_INVALID_NODE;
|
||||
}
|
||||
|
||||
STATIC UINT32 OsPmSysctrlUnregister(LosPmCB *pm, LosPmSysctrl *sysctrl)
|
||||
{
|
||||
(VOID)sysctrl;
|
||||
|
||||
UINT32 intSave = LOS_IntLock();
|
||||
OsPmSysctrlInit();
|
||||
pm->pmMode = LOS_SYS_NORMAL_SLEEP;
|
||||
LOS_IntRestore(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
UINT32 LOS_PmUnregister(LOS_PmNodeType type, VOID *node)
|
||||
{
|
||||
LosPmCB *pm = &g_pmCB;
|
||||
|
||||
if (node == NULL) {
|
||||
return LOS_ERRNO_PM_INVALID_PARAM;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case LOS_PM_TYPE_DEVICE:
|
||||
return OsPmDeviceUnregister(pm, (LosPmDevice *)node);
|
||||
case LOS_PM_TYPE_TICK_TIMER:
|
||||
return OsPmTickTimerUnregister(pm, (LosPmTickTimer *)node);
|
||||
case LOS_PM_TYPE_SYSCTRL:
|
||||
return OsPmSysctrlUnregister(pm, (LosPmSysctrl *)node);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return LOS_ERRNO_PM_INVALID_TYPE;
|
||||
}
|
||||
|
||||
VOID LOS_PmWakeSet(VOID)
|
||||
{
|
||||
UINT32 intSave;
|
||||
LosPmCB *pm = &g_pmCB;
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
pm->isWake = TRUE;
|
||||
LOS_IntRestore(intSave);
|
||||
return;
|
||||
}
|
||||
|
||||
LOS_SysSleepEnum LOS_PmModeGet(VOID)
|
||||
{
|
||||
LOS_SysSleepEnum mode;
|
||||
LosPmCB *pm = &g_pmCB;
|
||||
|
||||
UINT32 intSave = LOS_IntLock();
|
||||
mode = pm->pmMode;
|
||||
LOS_IntRestore(intSave);
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
UINT32 LOS_PmModeSet(LOS_SysSleepEnum mode)
|
||||
{
|
||||
UINT32 intSave;
|
||||
LosPmCB *pm = &g_pmCB;
|
||||
INT32 sleepMode = (INT32)mode;
|
||||
|
||||
if ((sleepMode < 0) || (sleepMode > LOS_SYS_SHUTDOWN)) {
|
||||
return LOS_ERRNO_PM_INVALID_MODE;
|
||||
}
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
if ((mode != LOS_SYS_NORMAL_SLEEP) && (pm->device == NULL)) {
|
||||
LOS_IntRestore(intSave);
|
||||
return LOS_ERRNO_PM_DEVICE_NULL;
|
||||
}
|
||||
|
||||
if ((mode == LOS_SYS_LIGHT_SLEEP) && (pm->sysctrl->lightSuspend == NULL)) {
|
||||
LOS_IntRestore(intSave);
|
||||
return LOS_ERRNO_PM_HANDLER_NULL;
|
||||
}
|
||||
|
||||
if ((mode == LOS_SYS_DEEP_SLEEP) && (pm->sysctrl->deepSuspend == NULL)) {
|
||||
LOS_IntRestore(intSave);
|
||||
return LOS_ERRNO_PM_HANDLER_NULL;
|
||||
}
|
||||
|
||||
if ((mode == LOS_SYS_SHUTDOWN) && (pm->sysctrl->shutdownSuspend == NULL)) {
|
||||
LOS_IntRestore(intSave);
|
||||
return LOS_ERRNO_PM_HANDLER_NULL;
|
||||
}
|
||||
|
||||
pm->pmMode = mode;
|
||||
LOS_IntRestore(intSave);
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
#if (LOSCFG_KERNEL_PM_DEBUG == 1)
|
||||
VOID LOS_PmLockInfoShow(VOID)
|
||||
{
|
||||
UINT32 intSave;
|
||||
LosPmCB *pm = &g_pmCB;
|
||||
OsPmLockCB *lock = NULL;
|
||||
LOS_DL_LIST *head = &pm->lockList;
|
||||
LOS_DL_LIST *list = head->pstNext;
|
||||
|
||||
PRINTK("Name Count\n\r");
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
while (list != head) {
|
||||
lock = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list);
|
||||
PRINTK("%-30s%5u\n\r", lock->name, lock->count);
|
||||
list = list->pstNext;
|
||||
}
|
||||
LOS_IntRestore(intSave);
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
UINT32 OsPmLockRequest(const CHAR *name, UINT32 swtmrID)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINT32 ret = LOS_ERRNO_PM_NOT_LOCK;
|
||||
LosPmCB *pm = &g_pmCB;
|
||||
OsPmLockCB *listNode = NULL;
|
||||
OsPmLockCB *lock = NULL;
|
||||
LOS_DL_LIST *head = &pm->lockList;
|
||||
LOS_DL_LIST *list = head->pstNext;
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
while (list != head) {
|
||||
listNode = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list);
|
||||
if (strcmp(name, listNode->name) == 0) {
|
||||
lock = listNode;
|
||||
break;
|
||||
}
|
||||
|
||||
list = list->pstNext;
|
||||
}
|
||||
|
||||
if (lock == NULL) {
|
||||
lock = LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(OsPmLockCB));
|
||||
if (lock == NULL) {
|
||||
LOS_IntRestore(intSave);
|
||||
return LOS_NOK;
|
||||
}
|
||||
lock->name = (CHAR *)name;
|
||||
lock->count = 1;
|
||||
lock->swtmrID = swtmrID;
|
||||
LOS_ListTailInsert(head, &lock->list);
|
||||
} else if (lock->count < OS_PM_LOCK_MAX) {
|
||||
lock->count++;
|
||||
}
|
||||
|
||||
if ((lock->swtmrID != OS_INVALID) && (lock->count > 1)) {
|
||||
lock->count--;
|
||||
LOS_IntRestore(intSave);
|
||||
return LOS_ERRNO_PM_ALREADY_LOCK;
|
||||
}
|
||||
|
||||
if (pm->lock < OS_PM_LOCK_MAX) {
|
||||
pm->lock++;
|
||||
ret = LOS_OK;
|
||||
}
|
||||
|
||||
LOS_IntRestore(intSave);
|
||||
return ret;
|
||||
}
|
||||
|
||||
UINT32 LOS_PmLockRequest(const CHAR *name)
|
||||
{
|
||||
if (name == NULL) {
|
||||
return LOS_ERRNO_PM_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return OsPmLockRequest(name, OS_INVALID);
|
||||
}
|
||||
|
||||
UINT32 LOS_PmLockRelease(const CHAR *name)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINT32 ret = LOS_ERRNO_PM_NOT_LOCK;
|
||||
LosPmCB *pm = &g_pmCB;
|
||||
OsPmLockCB *lock = NULL;
|
||||
OsPmLockCB *listNode = NULL;
|
||||
LOS_DL_LIST *head = &pm->lockList;
|
||||
LOS_DL_LIST *list = head->pstNext;
|
||||
OsPmLockCB *lockFree = NULL;
|
||||
BOOL isRelease = FALSE;
|
||||
UINT32 mode;
|
||||
|
||||
if (name == NULL) {
|
||||
return LOS_ERRNO_PM_INVALID_PARAM;
|
||||
}
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
mode = (UINT32)pm->pmMode;
|
||||
while (list != head) {
|
||||
listNode = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list);
|
||||
if (strcmp(name, listNode->name) == 0) {
|
||||
lock = listNode;
|
||||
break;
|
||||
}
|
||||
|
||||
list = list->pstNext;
|
||||
}
|
||||
|
||||
if (lock == NULL) {
|
||||
LOS_IntRestore(intSave);
|
||||
return LOS_ERRNO_PM_NOT_LOCK;
|
||||
} else if (lock->count > 0) {
|
||||
lock->count--;
|
||||
if (lock->count == 0) {
|
||||
LOS_ListDelete(&lock->list);
|
||||
lockFree = lock;
|
||||
}
|
||||
}
|
||||
|
||||
if (pm->lock > 0) {
|
||||
pm->lock--;
|
||||
if (pm->lock == 0) {
|
||||
isRelease = TRUE;
|
||||
}
|
||||
ret = LOS_OK;
|
||||
}
|
||||
LOS_IntRestore(intSave);
|
||||
|
||||
if (lockFree != NULL) {
|
||||
(VOID)LOS_SwtmrDelete(lockFree->swtmrID);
|
||||
(VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, lockFree);
|
||||
}
|
||||
|
||||
if (isRelease && (mode > LOS_SYS_NORMAL_SLEEP)) {
|
||||
(VOID)LOS_EventWrite(&g_pmEvent, PM_EVENT_LOCK_RELEASE);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
VOID OsPmFreezeTaskUnsafe(UINT32 taskID)
|
||||
{
|
||||
UINT64 responseTime;
|
||||
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
|
||||
|
||||
responseTime = GET_SORTLIST_VALUE(&taskCB->sortList);
|
||||
OsDeleteSortLink(&taskCB->sortList, OS_SORT_LINK_TASK);
|
||||
SET_SORTLIST_VALUE(&taskCB->sortList, responseTime);
|
||||
taskCB->taskStatus |= OS_TASK_FALG_FREEZE;
|
||||
return;
|
||||
}
|
||||
|
||||
VOID OsPmUnfreezeTaskUnsafe(UINT32 taskID)
|
||||
{
|
||||
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
|
||||
UINT64 currTime, responseTime;
|
||||
UINT32 remainTick;
|
||||
|
||||
taskCB->taskStatus &= ~OS_TASK_FALG_FREEZE;
|
||||
currTime = OsGetCurrSchedTimeCycle();
|
||||
responseTime = GET_SORTLIST_VALUE(&taskCB->sortList);
|
||||
if (responseTime > currTime) {
|
||||
remainTick = ((responseTime - currTime) + OS_CYCLE_PER_TICK - 1) / OS_CYCLE_PER_TICK;
|
||||
OsAdd2SortLink(&taskCB->sortList, currTime, remainTick, OS_SORT_LINK_TASK);
|
||||
return;
|
||||
}
|
||||
|
||||
SET_SORTLIST_VALUE(&taskCB->sortList, OS_SORT_LINK_INVALID_TIME);
|
||||
if (taskCB->taskStatus & OS_TASK_STATUS_PEND) {
|
||||
LOS_ListDelete(&taskCB->pendList);
|
||||
}
|
||||
taskCB->taskStatus &= ~(OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_PEND);
|
||||
return;
|
||||
}
|
||||
|
||||
STATIC VOID OsPmSwtmrHandler(UINT32 arg)
|
||||
{
|
||||
const CHAR *name = (const CHAR *)arg;
|
||||
UINT32 ret = LOS_PmLockRelease(name);
|
||||
if (ret != LOS_OK) {
|
||||
PRINT_ERR("Pm delay lock %s release faled! : 0x%x\n", name, ret);
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 LOS_PmTimeLockRequest(const CHAR *name, UINT64 millisecond)
|
||||
{
|
||||
UINT32 ticks;
|
||||
UINT32 swtmrID;
|
||||
UINT32 ret;
|
||||
|
||||
if ((name == NULL) || !millisecond) {
|
||||
return LOS_ERRNO_PM_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ticks = (UINT32)((millisecond + OS_MS_PER_TICK - 1) / OS_MS_PER_TICK);
|
||||
#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1)
|
||||
ret = LOS_SwtmrCreate(ticks, LOS_SWTMR_MODE_ONCE, OsPmSwtmrHandler, &swtmrID, (UINT32)(UINTPTR)name,
|
||||
OS_SWTMR_ROUSES_ALLOW, OS_SWTMR_ALIGN_INSENSITIVE);
|
||||
#else
|
||||
ret = LOS_SwtmrCreate(ticks, LOS_SWTMR_MODE_ONCE, OsPmSwtmrHandler, &swtmrID, (UINT32)(UINTPTR)name);
|
||||
#endif
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = OsPmLockRequest(name, swtmrID);
|
||||
if (ret != LOS_OK) {
|
||||
(VOID)LOS_SwtmrDelete(swtmrID);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = LOS_SwtmrStart(swtmrID);
|
||||
if (ret != LOS_OK) {
|
||||
(VOID)LOS_PmLockRelease(name);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
UINT32 LOS_PmReadLock(VOID)
|
||||
{
|
||||
UINT32 ret = LOS_EventRead(&g_pmEvent, PM_EVENT_LOCK_MASK, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER);
|
||||
if (ret > PM_EVENT_LOCK_MASK) {
|
||||
PRINT_ERR("%s event read failed! ERROR: 0x%x\n", __FUNCTION__, ret);
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
UINT32 LOS_PmSuspend(UINT32 wakeCount)
|
||||
{
|
||||
(VOID)wakeCount;
|
||||
return OsPmSuspendSleep(&g_pmCB);
|
||||
}
|
||||
|
||||
STATIC VOID OsPmSleepTimeSet(UINT64 sleepTime)
|
||||
{
|
||||
g_pmSleepTime = sleepTime;
|
||||
}
|
||||
|
||||
BOOL OsIsPmMode(VOID)
|
||||
{
|
||||
LosPmCB *pm = &g_pmCB;
|
||||
|
||||
UINT32 intSave = LOS_IntLock();
|
||||
if ((pm->sysMode != LOS_SYS_NORMAL_SLEEP) && (pm->lock == 0)) {
|
||||
LOS_IntRestore(intSave);
|
||||
return TRUE;
|
||||
}
|
||||
LOS_IntRestore(intSave);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
UINT32 OsPmInit(VOID)
|
||||
{
|
||||
UINT32 ret;
|
||||
LosPmCB *pm = &g_pmCB;
|
||||
|
||||
(VOID)memset_s(pm, sizeof(LosPmCB), 0, sizeof(LosPmCB));
|
||||
|
||||
pm->pmMode = LOS_SYS_NORMAL_SLEEP;
|
||||
LOS_ListInit(&pm->lockList);
|
||||
(VOID)LOS_EventInit(&g_pmEvent);
|
||||
|
||||
ret = OsSchedRealSleepTimeSet(OsPmSleepTimeSet);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = OsPmEnterHandlerSet(OsPmNormalSleep);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
OsPmSysctrlInit();
|
||||
pm->sysctrl = &g_sysctrl;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
478
components/power/los_pm.h
Normal file
478
components/power/los_pm.h
Normal file
@@ -0,0 +1,478 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_PM_H
|
||||
#define _LOS_PM_H
|
||||
|
||||
#include "los_config.h"
|
||||
#include "los_compiler.h"
|
||||
#include "los_list.h"
|
||||
#include "los_error.h"
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* Pm error code: Invalid low power mode.
|
||||
*
|
||||
* Value: 0x02002001
|
||||
*
|
||||
*/
|
||||
#define LOS_ERRNO_PM_INVALID_MODE LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x01)
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* Pm error code: Invalid input parameter.
|
||||
*
|
||||
* Value: 0x02002002
|
||||
*
|
||||
*/
|
||||
#define LOS_ERRNO_PM_INVALID_PARAM LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x02)
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* Pm error code: The current mode is unlocked.
|
||||
*
|
||||
* Value: 0x02002003
|
||||
*
|
||||
*/
|
||||
#define LOS_ERRNO_PM_NOT_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x03)
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* Pm error code: The lock limit has been exceeded.
|
||||
*
|
||||
* Value: 0x02002004
|
||||
*
|
||||
*/
|
||||
#define LOS_ERRNO_PM_LOCK_LIMIT LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x04)
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* Pm error code: Invalid device node.
|
||||
*
|
||||
* Value: 0x02002005
|
||||
*
|
||||
*/
|
||||
#define LOS_ERRNO_PM_INVALID_NODE LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x05)
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* Pm error code: Invalid type.
|
||||
*
|
||||
* Value: 0x02002006
|
||||
*
|
||||
*/
|
||||
#define LOS_ERRNO_PM_INVALID_TYPE LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x06)
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* Pm error code: The hook for mode is not implemented.
|
||||
*
|
||||
* Value: 0x02002007
|
||||
*
|
||||
*/
|
||||
#define LOS_ERRNO_PM_HANDLER_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x07)
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* Pm error code: Deep and shutdown must implement the Tick Timer related interface.
|
||||
*
|
||||
* Value: 0x02002008
|
||||
*
|
||||
*/
|
||||
#define LOS_ERRNO_PM_TICK_TIMER_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x08)
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* Pm error code: Device is not registered.
|
||||
*
|
||||
* Value: 0x02002009
|
||||
*
|
||||
*/
|
||||
#define LOS_ERRNO_PM_DEVICE_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x09)
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* Pm error code: The delay lock has already been activated.
|
||||
*
|
||||
* Value: 0x0200200a
|
||||
*
|
||||
*/
|
||||
#define LOS_ERRNO_PM_ALREADY_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x0a)
|
||||
|
||||
typedef enum {
|
||||
LOS_SYS_NORMAL_SLEEP = 0,
|
||||
LOS_SYS_LIGHT_SLEEP,
|
||||
LOS_SYS_DEEP_SLEEP,
|
||||
LOS_SYS_SHUTDOWN,
|
||||
} LOS_SysSleepEnum;
|
||||
|
||||
typedef enum {
|
||||
LOS_PM_TYPE_DEVICE = 0,
|
||||
LOS_PM_TYPE_TICK_TIMER,
|
||||
LOS_PM_TYPE_SYSCTRL,
|
||||
} LOS_PmNodeType;
|
||||
|
||||
typedef struct {
|
||||
UINT32 (*suspend)(UINT32 mode); /* The device enters low power consumption, Unlocked task scheduling. */
|
||||
VOID (*resume)(UINT32 mode); /* The device exits from low power consumption, Unlocked task scheduling. */
|
||||
} LosPmDevice;
|
||||
|
||||
typedef struct {
|
||||
UINT32 freq; /* The frequency of the low power timer */
|
||||
VOID (*timerStart)(UINT64); /* Start the low power timer */
|
||||
VOID (*timerStop)(VOID); /* Stop the low power timer */
|
||||
UINT64 (*timerCycleGet)(VOID); /* Gets the running time of the low power timer in unit cycle */
|
||||
VOID (*tickLock)(VOID); /* Pause the system tick timer */
|
||||
VOID (*tickUnlock)(VOID); /* Restore the system tick timer */
|
||||
} LosPmTickTimer;
|
||||
|
||||
typedef struct {
|
||||
/* Preparations before the CPU enters low power consumption.
|
||||
* All modes except normal mode are invoked.
|
||||
* Unlocked task scheduling.
|
||||
*/
|
||||
UINT32 (*early)(UINT32 mode);
|
||||
/* The system performs low-power recovery.
|
||||
* All modes except normal mode are invoked.
|
||||
* Unlocked task scheduling.
|
||||
*/
|
||||
VOID (*late)(UINT32 mode);
|
||||
/* The system enters the Normal sleep mode.
|
||||
* In normal mode, the value cannot be NULL.
|
||||
*/
|
||||
UINT32 (*normalSuspend)(VOID);
|
||||
/* The system recovers from normal sleep.
|
||||
* The value can be NULL.
|
||||
*/
|
||||
VOID (*normalResume)(VOID);
|
||||
/* The system enters the light sleep mode.
|
||||
* In light sleep mode, the value cannot be NULL.
|
||||
*/
|
||||
UINT32 (*lightSuspend)(VOID);
|
||||
/* The system recovers from light sleep.
|
||||
* The value can be NULL.
|
||||
*/
|
||||
VOID (*lightResume)(VOID);
|
||||
/* The system enters the deep sleep mode.
|
||||
* In deep sleep mode, the value cannot be NULL.
|
||||
*/
|
||||
UINT32 (*deepSuspend)(VOID);
|
||||
/* The system recovers from deep sleep.
|
||||
* The value can be NULL.
|
||||
*/
|
||||
VOID (*deepResume)(VOID);
|
||||
/* The system enters the shutdown mode.
|
||||
* In shutdown mode, the value cannot be NULL.
|
||||
*/
|
||||
UINT32 (*shutdownSuspend)(VOID);
|
||||
/* The system recovers from shutdown.
|
||||
* In shutdown mode, the value cannot be NULL.
|
||||
*/
|
||||
VOID (*shutdownResume)(VOID);
|
||||
} LosPmSysctrl;
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* @brief Initialize system low power frame.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to initialize the system low power frame.
|
||||
*
|
||||
* @attention None.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @retval error code, LOS_OK means success.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see
|
||||
*/
|
||||
UINT32 OsPmInit(VOID);
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* @brief Whether the low power consumption condition is met.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to check whether low power consumption is met.
|
||||
*
|
||||
* @attention None.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @retval TRUE or FALSE.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see
|
||||
*/
|
||||
BOOL OsIsPmMode(VOID);
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* @brief Freeze delay tasks, internal interfaces between modules.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to freeze delay tasks.
|
||||
*
|
||||
* @attention None.
|
||||
*
|
||||
* @param taskID [IN] task ID.
|
||||
*
|
||||
* @retval None.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see OsPmUnfreezeTaskUnsafe
|
||||
*/
|
||||
VOID OsPmFreezeTaskUnsafe(UINT32 taskID);
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* @brief Unfreeze delayed tasks, internal interface between modules.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to unfreeze delayed tasks.
|
||||
*
|
||||
* @attention None.
|
||||
*
|
||||
* @param taskID [IN] task ID.
|
||||
*
|
||||
* @retval None.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see OsPmFreezeTaskUnsafe
|
||||
*/
|
||||
VOID OsPmUnfreezeTaskUnsafe(UINT32 taskID);
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* @brief Register a power management node.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to register a power management node.
|
||||
*
|
||||
* @attention None.
|
||||
*
|
||||
* @param type [IN] The types supported by the PM module.
|
||||
* @param node [IN] power management node.
|
||||
*
|
||||
* @retval error code, LOS_OK means success.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see LOS_PmUnregister
|
||||
*/
|
||||
UINT32 LOS_PmRegister(LOS_PmNodeType type, VOID *node);
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* @brief Unregister a power management node.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to unregister a power management node.
|
||||
*
|
||||
* @attention None.
|
||||
*
|
||||
* @param type [IN] The types supported by the PM module.
|
||||
* @param node [IN] power management node.
|
||||
*
|
||||
* @retval error code, LOS_OK means success.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see LOS_PmRegister
|
||||
*/
|
||||
UINT32 LOS_PmUnregister(LOS_PmNodeType type, VOID *node);
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* @brief Set the system wake up flag.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to set the system wake-up flag.
|
||||
*
|
||||
* @attention None.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @retval None.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see
|
||||
*/
|
||||
VOID LOS_PmWakeSet(VOID);
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* @brief Get the low power mode of the current system.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to get the low power mode of the current system.
|
||||
*
|
||||
* @attention None.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @retval error code, LOS_OK means success.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see LOS_PmModeSet
|
||||
*/
|
||||
LOS_SysSleepEnum LOS_PmModeGet(VOID);
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* @brief Set low power mode.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to set low power mode.
|
||||
*
|
||||
* @attention None.
|
||||
*
|
||||
* @param mode [IN] low power mode.
|
||||
*
|
||||
* @retval error code, LOS_OK means success.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see LOS_PmModeGet
|
||||
*/
|
||||
UINT32 LOS_PmModeSet(LOS_SysSleepEnum mode);
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* @brief Request to obtain the lock in current mode, so that the system will not enter
|
||||
* this mode when it enters the idle task next time.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to obtain the lock in current mode.
|
||||
*
|
||||
* @attention None.
|
||||
*
|
||||
* @param name [IN] Who requests the lock.
|
||||
*
|
||||
* @retval error code, LOS_OK means success.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see LOS_PmLockRelease
|
||||
*/
|
||||
UINT32 LOS_PmLockRequest(const CHAR *name);
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* @brief Request to obtain the lock in current mode, so that the system will not enter
|
||||
* this mode when it enters the idle task next time. After the specified interval, the
|
||||
* lock is automatically released.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to obtain the delay lock in current mode.
|
||||
*
|
||||
* @attention None.
|
||||
*
|
||||
* @param name [IN] Who requests the lock.
|
||||
* @param millisecond [IN] Specifies the time to automatically release the lock.
|
||||
*
|
||||
* @retval error code, LOS_OK means success.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see LOS_PmLockRelease
|
||||
*/
|
||||
UINT32 LOS_PmTimeLockRequest(const CHAR *name, UINT64 millisecond);
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* @brief Release the lock in current mode so that the next time the system enters
|
||||
* the idle task, it will enter this mode.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to release the lock in current mode.
|
||||
*
|
||||
* @attention None.
|
||||
*
|
||||
* @param name [IN] Who releases the lock.
|
||||
*
|
||||
* @retval error code, LOS_OK means success.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see LOS_PmLockRequest
|
||||
*/
|
||||
UINT32 LOS_PmLockRelease(const CHAR *name);
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* @brief Gets the current PM lock status.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to Get the current PM lock status.
|
||||
*
|
||||
* @attention None.
|
||||
*
|
||||
* @param NA.
|
||||
*
|
||||
* @retval Number of awakening sources of the device.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see
|
||||
*/
|
||||
UINT32 LOS_PmReadLock(VOID);
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* @brief The system enters the low-power flow.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to enter the system into a low-power process.
|
||||
*
|
||||
* @attention None.
|
||||
*
|
||||
* @param wakeCount [IN] Number of wake sources.
|
||||
*
|
||||
* @retval error code, LOS_OK means success.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see
|
||||
*/
|
||||
UINT32 LOS_PmSuspend(UINT32 wakeCount);
|
||||
|
||||
/**
|
||||
* @ingroup los_pm
|
||||
* @brief Output the locking information of the pm lock.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to output the locking information of the pm lock.
|
||||
*
|
||||
* @attention None.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @retval error code, LOS_OK means success.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see LOS_PmLockRequest
|
||||
*/
|
||||
VOID LOS_PmLockInfoShow(VOID);
|
||||
#endif
|
||||
60
components/shell/BUILD.gn
Normal file
60
components/shell/BUILD.gn
Normal file
@@ -0,0 +1,60 @@
|
||||
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
# of conditions and the following disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
# to endorse or promote products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import("//kernel/liteos_m/config.gni")
|
||||
|
||||
static_library("shell") {
|
||||
sources = [
|
||||
"src/base/shcmd.c",
|
||||
"src/base/shcmdparse.c",
|
||||
"src/base/shmsg.c",
|
||||
"src/base/show.c",
|
||||
"src/cmds/date_shell.c",
|
||||
"src/cmds/fullpath.c",
|
||||
"src/cmds/mempt_shellcmd.c",
|
||||
"src/cmds/shell_shellcmd.c",
|
||||
"src/cmds/task_shellcmd.c",
|
||||
"src/cmds/vfs_shellcmd.c",
|
||||
]
|
||||
|
||||
include_dirs = [
|
||||
"../../kernel/arch/include",
|
||||
"../../kernel/include",
|
||||
"../../utils",
|
||||
"./include",
|
||||
]
|
||||
|
||||
if (enable_ohos_kernel_liteos_m_lwip) {
|
||||
defines = [ "LWIP_SHELLCMD_ENABLE" ]
|
||||
}
|
||||
deps = [
|
||||
"//kernel/liteos_m/kal/posix",
|
||||
"//third_party/bounds_checking_function:libsec_static",
|
||||
]
|
||||
}
|
||||
117
components/shell/include/shcmd.h
Normal file
117
components/shell/include/shcmd.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _HWLITEOS_SHELL_SHCMD_H
|
||||
#define _HWLITEOS_SHELL_SHCMD_H
|
||||
|
||||
#include "string.h"
|
||||
#include "stdlib.h"
|
||||
#include "los_list.h"
|
||||
#include "shcmdparse.h"
|
||||
#include "show.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef BOOL (*CmdVerifyTransID)(UINT32 transID);
|
||||
|
||||
typedef struct {
|
||||
CmdType cmdType;
|
||||
const CHAR *cmdKey;
|
||||
UINT32 paraNum;
|
||||
CmdCallBackFunc cmdHook;
|
||||
} CmdItem;
|
||||
|
||||
typedef struct {
|
||||
LOS_DL_LIST list;
|
||||
CmdItem *cmd;
|
||||
} CmdItemNode;
|
||||
|
||||
/* global info for shell module */
|
||||
typedef struct {
|
||||
CmdItemNode cmdList;
|
||||
UINT32 listNum;
|
||||
UINT32 initMagicFlag;
|
||||
UINT32 muxLock;
|
||||
CmdVerifyTransID transIdHook;
|
||||
} CmdModInfo;
|
||||
|
||||
typedef struct {
|
||||
UINT32 count;
|
||||
LOS_DL_LIST list;
|
||||
CHAR cmdString[0];
|
||||
} CmdKeyLink;
|
||||
|
||||
#define SHELLCMD_ENTRY(l, cmdType, cmdKey, paraNum, cmdHook) \
|
||||
CmdItem l LOS_HAL_TABLE_ENTRY(shellcmd) = { \
|
||||
cmdType, \
|
||||
cmdKey, \
|
||||
paraNum, \
|
||||
cmdHook \
|
||||
}
|
||||
|
||||
#define NEED_NEW_LINE(timesPrint, lineCap) ((timesPrint) % (lineCap) == 0)
|
||||
#define SCREEN_IS_FULL(timesPrint, lineCap) ((timesPrint) >= ((lineCap) * DEFAULT_SCREEN_HEIGNT))
|
||||
|
||||
extern CmdModInfo *OsCmdInfoGet(VOID);
|
||||
extern UINT32 OsCmdExec(CmdParsed *cmdParsed, CHAR *cmdStr);
|
||||
extern UINT32 OsCmdKeyShift(const CHAR *cmdKey, CHAR *cmdOut, UINT32 size);
|
||||
extern UINT32 OsShellKeyInit(ShellCB *shellCB);
|
||||
extern VOID OsShellKeyDeInit(CmdKeyLink *cmdKeyLink);
|
||||
extern UINT32 OsShellSysCmdRegister(VOID);
|
||||
extern int VfsNormalizePath(const char *directory, const char *filename, char **pathname);
|
||||
extern INT32 OsShellCmdDate(INT32 argc, const CHAR **argv);
|
||||
extern INT32 OsShellCmdDumpTask(INT32 argc, const CHAR **argv);
|
||||
extern UINT32 OsShellCmdFree(INT32 argc, const CHAR **argv);
|
||||
extern UINT32 lwip_ifconfig(INT32 argc, const CHAR **argv);
|
||||
extern UINT32 OsShellPing(INT32 argc, const CHAR **argv);
|
||||
extern INT32 OsShellCmdTouch(INT32 argc, const CHAR **argv);
|
||||
extern INT32 OsShellCmdLs(INT32 argc, const CHAR **argv);
|
||||
extern INT32 OsShellCmdPwd(INT32 argc, const CHAR **argv);
|
||||
extern INT32 OsShellCmdCd(INT32 argc, const CHAR **argv);
|
||||
extern INT32 OsShellCmdCat(INT32 argc, const CHAR **argv);
|
||||
extern INT32 OsShellCmdRm(INT32 argc, const CHAR **argv);
|
||||
extern INT32 OsShellCmdRmdir(INT32 argc, const CHAR **argv);
|
||||
extern INT32 OsShellCmdMkdir(INT32 argc, const CHAR **argv);
|
||||
extern INT32 OsShellCmdCp(INT32 argc, const CHAR **argv);
|
||||
extern INT32 OsShellCmdHelp(INT32 argc, const CHAR **argv);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* _HWLITEOS_SHELL_SHCMD_H */
|
||||
72
components/shell/include/shcmdparse.h
Normal file
72
components/shell/include/shcmdparse.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _HWLITEOS_SHELL_SHCMDPARSE_H
|
||||
#define _HWLITEOS_SHELL_SHCMDPARSE_H
|
||||
|
||||
#include "string.h"
|
||||
#include "show.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define CMD_PARSED_RETCODE_BASE LOS_OK
|
||||
#define CMD_PARSED_RETCODE_TYPE_INVALID (CMD_PARSED_RETCODE_BASE + 1)
|
||||
#define CMD_PARSED_RETCODE_PARAM_OVERTOP (CMD_PARSED_RETCODE_BASE + 3)
|
||||
#define CMD_PARSED_RETCODE_CMDKEY_NOTFOUND (CMD_PARSED_RETCODE_BASE + 4)
|
||||
|
||||
typedef UINT32 (*FUNC_ONE_TOKEN)(VOID *ctx, UINT32 index, CHAR *token);
|
||||
|
||||
/*
|
||||
* Description: the info struct after cmd parser
|
||||
*/
|
||||
typedef struct {
|
||||
UINT32 paramCnt; /* count of para */
|
||||
CmdType cmdType; /* cmd type, judge cmd keyword */
|
||||
CHAR cmdKeyword[CMD_KEY_LEN]; /* cmd keyword str */
|
||||
CHAR *paramArray[CMD_MAX_PARAS];
|
||||
} CmdParsed;
|
||||
|
||||
extern UINT32 OsCmdParse(CHAR *cmdStr, CmdParsed *cmdParsed);
|
||||
extern CHAR *OsCmdParseStrdup(const CHAR *str);
|
||||
extern UINT32 OsCmdParseOneToken(CmdParsed *cmdParsed, UINT32 index, const CHAR *token);
|
||||
extern UINT32 OsCmdTokenSplit(CHAR *cmdStr, CHAR split, CmdParsed *cmdParsed);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* _HWLITEOS_SHELL_SHCMDPARSE_H */
|
||||
134
components/shell/include/shell.h
Normal file
134
components/shell/include/shell.h
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _HWLITEOS_SHELL_H
|
||||
#define _HWLITEOS_SHELL_H
|
||||
|
||||
#include "pthread.h"
|
||||
#include "limits.h"
|
||||
#include "los_compiler.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define OS_ERRNO_SHELL_NO_HOOK LOS_ERRNO_OS_ERROR(LOS_MOD_SHELL, 0x00)
|
||||
#define OS_ERRNO_SHELL_CMDREG_PARA_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_SHELL, 0x01)
|
||||
#define OS_ERRNO_SHELL_CMDREG_CMD_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_SHELL, 0x02)
|
||||
#define OS_ERRNO_SHELL_CMDREG_CMD_EXIST LOS_ERRNO_OS_ERROR(LOS_MOD_SHELL, 0x03)
|
||||
#define OS_ERRNO_SHELL_CMDREG_MEMALLOC_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_SHELL, 0x04)
|
||||
#define OS_ERRNO_SHELL_SHOW_HOOK_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SHELL, 0x05)
|
||||
#define OS_ERRNO_SHELL_SHOW_HOOK_EXIST LOS_ERRNO_OS_ERROR(LOS_MOD_SHELL, 0x06)
|
||||
#define OS_ERRNO_SHELL_SHOW_HOOK_TOO_MUCH LOS_ERRNO_OS_ERROR(LOS_MOD_SHELL, 0x07)
|
||||
#define OS_ERRNO_SHELL_NOT_INIT LOS_ERRNO_OS_ERROR(LOS_MOD_SHELL, 0x08)
|
||||
#define OS_ERRNO_SHELL_CMD_HOOK_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SHELL, 0x09)
|
||||
#define OS_ERRNO_SHELL_FIFO_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_SHELL, 0x10)
|
||||
|
||||
/* Max len of show str */
|
||||
#define SHOW_MAX_LEN CMD_MAX_LEN
|
||||
|
||||
#define XARGS 0xFFFFFFFF /* default args */
|
||||
|
||||
#define CMD_MAX_PARAS 32
|
||||
#define CMD_KEY_LEN 16U
|
||||
#define CMD_MAX_LEN (256U + CMD_KEY_LEN)
|
||||
#define CMD_KEY_NUM 32
|
||||
#define CMD_HISTORY_LEN 10
|
||||
#define CMD_MAX_PATH 256
|
||||
#define DEFAULT_SCREEN_WIDTH 80
|
||||
#define DEFAULT_SCREEN_HEIGNT 24
|
||||
|
||||
#define SHELL_MODE 0
|
||||
#define OTHER_MODE 1
|
||||
|
||||
#define SWITCH_QUOTES_STATUS(qu) do { \
|
||||
if ((qu) == TRUE) { \
|
||||
(qu) = FALSE; \
|
||||
} else { \
|
||||
(qu) = TRUE; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define QUOTES_STATUS_CLOSE(qu) ((qu) == FALSE)
|
||||
#define QUOTES_STATUS_OPEN(qu) ((qu) == TRUE)
|
||||
|
||||
typedef struct {
|
||||
UINT32 consoleID;
|
||||
UINT32 shellTaskHandle;
|
||||
UINT32 shellEntryHandle;
|
||||
VOID *cmdKeyLink;
|
||||
VOID *cmdHistoryKeyLink;
|
||||
VOID *cmdMaskKeyLink;
|
||||
UINT32 shellBufOffset;
|
||||
UINT32 shellKeyType;
|
||||
pthread_mutex_t keyMutex;
|
||||
pthread_mutex_t historyMutex;
|
||||
CHAR shellBuf[SHOW_MAX_LEN];
|
||||
CHAR shellWorkingDirectory[PATH_MAX];
|
||||
} ShellCB;
|
||||
|
||||
/* All support cmd types */
|
||||
typedef enum {
|
||||
CMD_TYPE_SHOW = 0,
|
||||
CMD_TYPE_STD = 1,
|
||||
CMD_TYPE_EX = 2,
|
||||
CMD_TYPE_BUTT
|
||||
} CmdType;
|
||||
|
||||
typedef enum {
|
||||
CMD_KEY_UP = 0,
|
||||
CMD_KEY_DOWN = 1,
|
||||
CMD_KEY_RIGHT = 2,
|
||||
CMD_KEY_LEFT = 4,
|
||||
CMD_KEY_BUTT
|
||||
} CmdKeyDirection;
|
||||
|
||||
/*
|
||||
* Hook for user-defined debug function
|
||||
* Unify differnt module's func for registration
|
||||
*/
|
||||
typedef UINT32 (*CmdCallBackFunc)(UINT32 argc, const CHAR **argv);
|
||||
|
||||
/* External interface, need reserved */
|
||||
typedef CmdCallBackFunc CMD_CBK_FUNC;
|
||||
typedef CmdType CMD_TYPE_E;
|
||||
|
||||
extern UINT32 osCmdReg(CmdType cmdType, const CHAR *cmdKey, UINT32 paraNum, CmdCallBackFunc cmdProc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _HWLITEOS_SHELL_H */
|
||||
57
components/shell/include/shmsg.h
Normal file
57
components/shell/include/shmsg.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _HWLITEOS_SHELL_SHMSG_H
|
||||
#define _HWLITEOS_SHELL_SHMSG_H
|
||||
|
||||
#include "shell.h"
|
||||
#include "shcmdparse.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
extern UINT32 ShellMsgTypeGet(CmdParsed *cmdParsed, const CHAR *cmdType);
|
||||
extern void ExecCmdline(const char *cmdline);
|
||||
|
||||
#define SHELL_CMD_PARSE_EVENT 0x111
|
||||
|
||||
#define SH_OK 0
|
||||
#define SH_NOK 1
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _HWLITEOS_SHELL_SHMSG_H */
|
||||
66
components/shell/include/show.h
Normal file
66
components/shell/include/show.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _HWLITEOS_SHELL_SHOW_H
|
||||
#define _HWLITEOS_SHELL_SHOW_H
|
||||
|
||||
#include "shell.h"
|
||||
#include "los_debug.h"
|
||||
#include "errno.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
extern CHAR *OsShellGetWorkingDirtectory(VOID);
|
||||
extern UINT32 OsShellInit(INT32 consoleId);
|
||||
extern INT32 OsShellDeinit(INT32 consoleId);
|
||||
|
||||
static inline void SetErrno(int errcode)
|
||||
{
|
||||
errno = errcode;
|
||||
}
|
||||
|
||||
static inline void SetErr(int errcode, const char *errMessage)
|
||||
{
|
||||
SetErrno(errcode);
|
||||
PRINTK(errMessage);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _HWLITEOS_SHELL_SHOW_H */
|
||||
454
components/shell/src/base/shcmd.c
Executable file
454
components/shell/src/base/shcmd.c
Executable file
@@ -0,0 +1,454 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "shcmd.h"
|
||||
#include "show.h"
|
||||
#include "shmsg.h"
|
||||
#include "stdlib.h"
|
||||
#include "unistd.h"
|
||||
#include "dirent.h"
|
||||
#include "securec.h"
|
||||
#include "los_mux.h"
|
||||
#include "los_memory.h"
|
||||
|
||||
#define SHELL_INIT_MAGIC_FLAG 0xABABABAB
|
||||
|
||||
STATIC CmdModInfo cmdInfo;
|
||||
ShellCB *g_shellCB = NULL;
|
||||
CmdItem g_shellcmdAll[] = {
|
||||
{CMD_TYPE_STD, "date", XARGS, (CmdCallBackFunc)OsShellCmdDate},
|
||||
{CMD_TYPE_EX, "task", 1, (CmdCallBackFunc)OsShellCmdDumpTask},
|
||||
{CMD_TYPE_EX, "free", XARGS, (CmdCallBackFunc)OsShellCmdFree},
|
||||
#ifdef LWIP_SHELLCMD_ENABLE
|
||||
{CMD_TYPE_EX, "ifconfig", XARGS, (CmdCallBackFunc)lwip_ifconfig},
|
||||
{CMD_TYPE_EX, "ping", XARGS, (CmdCallBackFunc)OsShellPing},
|
||||
#endif
|
||||
{CMD_TYPE_EX, "touch", XARGS, (CmdCallBackFunc)OsShellCmdTouch},
|
||||
{CMD_TYPE_EX, "ls", XARGS, (CmdCallBackFunc)OsShellCmdLs},
|
||||
{CMD_TYPE_EX, "pwd", XARGS, (CmdCallBackFunc)OsShellCmdPwd},
|
||||
{CMD_TYPE_EX, "cd", XARGS, (CmdCallBackFunc)OsShellCmdCd},
|
||||
{CMD_TYPE_EX, "cat", XARGS, (CmdCallBackFunc)OsShellCmdCat},
|
||||
{CMD_TYPE_EX, "rm", XARGS, (CmdCallBackFunc)OsShellCmdRm},
|
||||
{CMD_TYPE_EX, "rmdir", XARGS, (CmdCallBackFunc)OsShellCmdRmdir},
|
||||
{CMD_TYPE_EX, "mkdir", XARGS, (CmdCallBackFunc)OsShellCmdMkdir},
|
||||
{CMD_TYPE_EX, "cp", XARGS, (CmdCallBackFunc)OsShellCmdCp},
|
||||
{CMD_TYPE_EX, "help", 0, (CmdCallBackFunc)OsShellCmdHelp},
|
||||
};
|
||||
|
||||
CmdModInfo *OsCmdInfoGet(VOID)
|
||||
{
|
||||
return &cmdInfo;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: Pass in the string and clear useless space ,which inlcude:
|
||||
* 1) The overmatch space which is not be marked by Quote's area
|
||||
* Squeeze the overmatch space into one space
|
||||
* 2) Clear all space before first vaild charatctor
|
||||
* Input: cmdKey : Pass in the buff string, which is ready to be operated
|
||||
* cmdOut : Pass out the buffer string ,which has already been operated
|
||||
* size : cmdKey length
|
||||
*/
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdKeyShift(const CHAR *cmdKey, CHAR *cmdOut, UINT32 size)
|
||||
{
|
||||
CHAR *output = NULL;
|
||||
CHAR *outputBak = NULL;
|
||||
UINT32 len;
|
||||
INT32 ret;
|
||||
BOOL quotes = FALSE;
|
||||
|
||||
if ((cmdKey == NULL) || (cmdOut == NULL)) {
|
||||
return (UINT32)OS_ERROR;
|
||||
}
|
||||
|
||||
len = strlen(cmdKey);
|
||||
if (len >= size) {
|
||||
return (UINT32)OS_ERROR;
|
||||
}
|
||||
output = (CHAR*)LOS_MemAlloc(m_aucSysMem0, len + 1);
|
||||
if (output == NULL) {
|
||||
PRINTK("malloc failure in %s[%d]", __FUNCTION__, __LINE__);
|
||||
return (UINT32)OS_ERROR;
|
||||
}
|
||||
/* Backup the 'output' start address */
|
||||
outputBak = output;
|
||||
/* Scan each charactor in 'cmdKey',and squeeze the overmuch space and ignore invaild charactor */
|
||||
for (; *cmdKey != '\0'; cmdKey++) {
|
||||
/* Detected a Double Quotes, switch the matching status */
|
||||
if (*(cmdKey) == '\"') {
|
||||
SWITCH_QUOTES_STATUS(quotes);
|
||||
}
|
||||
/* Ignore the current charactor in following situation */
|
||||
/* 1) Quotes matching status is FALSE (which said that the space is not been marked by double quotes) */
|
||||
/* 2) Current charactor is a space */
|
||||
/* 3) Next charactor is a space too, or the string is been seeked to the end already(\0) */
|
||||
/* 4) Invaild charactor, such as single quotes */
|
||||
if ((*cmdKey == ' ') && ((*(cmdKey + 1) == ' ') || (*(cmdKey + 1) == '\0')) && QUOTES_STATUS_CLOSE(quotes)) {
|
||||
continue;
|
||||
}
|
||||
if (*cmdKey == '\'') {
|
||||
continue;
|
||||
}
|
||||
*output = *cmdKey;
|
||||
output++;
|
||||
}
|
||||
*output = '\0';
|
||||
/* Restore the 'output' start address */
|
||||
output = outputBak;
|
||||
len = strlen(output);
|
||||
/* Clear the space which is located at the first charactor in buffer */
|
||||
if (*outputBak == ' ') {
|
||||
output++;
|
||||
len--;
|
||||
}
|
||||
/* Copy out the buffer which is been operated already */
|
||||
ret = strncpy_s(cmdOut, size, output, len);
|
||||
if (ret != EOK) {
|
||||
PRINT_ERR("%s,%d strncpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
|
||||
(VOID)LOS_MemFree(m_aucSysMem0, output);
|
||||
return OS_ERROR;
|
||||
}
|
||||
cmdOut[len] = '\0';
|
||||
|
||||
(VOID)LOS_MemFree(m_aucSysMem0, output);
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR BOOL OsCmdKeyCheck(const CHAR *cmdKey)
|
||||
{
|
||||
const CHAR *temp = cmdKey;
|
||||
enum Stat {
|
||||
STAT_NONE,
|
||||
STAT_DIGIT,
|
||||
STAT_OTHER
|
||||
} state = STAT_NONE;
|
||||
|
||||
if (strlen(cmdKey) >= CMD_KEY_LEN) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while (*temp != '\0') {
|
||||
if (!((*temp <= '9') && (*temp >= '0')) &&
|
||||
!((*temp <= 'z') && (*temp >= 'a')) &&
|
||||
!((*temp <= 'Z') && (*temp >= 'A')) &&
|
||||
(*temp != '_') && (*temp != '-')) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((*temp >= '0') && (*temp <= '9')) {
|
||||
if (state == STAT_NONE) {
|
||||
state = STAT_DIGIT;
|
||||
}
|
||||
} else {
|
||||
state = STAT_OTHER;
|
||||
}
|
||||
|
||||
temp++;
|
||||
}
|
||||
|
||||
if (state == STAT_DIGIT) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OsCmdAscendingInsert(CmdItemNode *cmd)
|
||||
{
|
||||
CmdItemNode *cmdItem = NULL;
|
||||
CmdItemNode *cmdNext = NULL;
|
||||
|
||||
if (cmd == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (cmdItem = LOS_DL_LIST_ENTRY((&cmdInfo.cmdList.list)->pstPrev, CmdItemNode, list);
|
||||
&cmdItem->list != &(cmdInfo.cmdList.list); ) {
|
||||
cmdNext = LOS_DL_LIST_ENTRY(cmdItem->list.pstPrev, CmdItemNode, list);
|
||||
if (&cmdNext->list != &(cmdInfo.cmdList.list)) {
|
||||
if ((strncmp(cmdItem->cmd->cmdKey, cmd->cmd->cmdKey, strlen(cmd->cmd->cmdKey)) >= 0) &&
|
||||
(strncmp(cmdNext->cmd->cmdKey, cmd->cmd->cmdKey, strlen(cmd->cmd->cmdKey)) < 0)) {
|
||||
LOS_ListTailInsert(&(cmdItem->list), &(cmd->list));
|
||||
return;
|
||||
}
|
||||
cmdItem = cmdNext;
|
||||
} else {
|
||||
if (strncmp(cmd->cmd->cmdKey, cmdItem->cmd->cmdKey, strlen(cmd->cmd->cmdKey)) > 0) {
|
||||
cmdItem = cmdNext;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LOS_ListTailInsert(&(cmdItem->list), &(cmd->list));
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellKeyInit(ShellCB *shellCB)
|
||||
{
|
||||
CmdKeyLink *cmdKeyLink = NULL;
|
||||
CmdKeyLink *cmdHistoryLink = NULL;
|
||||
|
||||
if (shellCB == NULL) {
|
||||
return OS_ERROR;
|
||||
}
|
||||
cmdKeyLink = (CmdKeyLink *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdKeyLink));
|
||||
if (cmdKeyLink == NULL) {
|
||||
PRINT_ERR("Shell CmdKeyLink memory alloc error!\n");
|
||||
return OS_ERROR;
|
||||
}
|
||||
cmdHistoryLink = (CmdKeyLink *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdKeyLink));
|
||||
if (cmdHistoryLink == NULL) {
|
||||
(VOID)LOS_MemFree(m_aucSysMem0, cmdKeyLink);
|
||||
PRINT_ERR("Shell CmdHistoryLink memory alloc error!\n");
|
||||
return OS_ERROR;
|
||||
}
|
||||
|
||||
cmdKeyLink->count = 0;
|
||||
LOS_ListInit(&(cmdKeyLink->list));
|
||||
shellCB->cmdKeyLink = (VOID *)cmdKeyLink;
|
||||
|
||||
cmdHistoryLink->count = 0;
|
||||
LOS_ListInit(&(cmdHistoryLink->list));
|
||||
shellCB->cmdHistoryKeyLink = (VOID *)cmdHistoryLink;
|
||||
shellCB->cmdMaskKeyLink = (VOID *)cmdHistoryLink;
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OsShellKeyDeInit(CmdKeyLink *cmdKeyLink)
|
||||
{
|
||||
CmdKeyLink *cmdtmp = NULL;
|
||||
if (cmdKeyLink == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (!LOS_ListEmpty(&(cmdKeyLink->list))) {
|
||||
cmdtmp = LOS_DL_LIST_ENTRY(cmdKeyLink->list.pstNext, CmdKeyLink, list);
|
||||
LOS_ListDelete(&cmdtmp->list);
|
||||
(VOID)LOS_MemFree(m_aucSysMem0, cmdtmp);
|
||||
}
|
||||
|
||||
cmdKeyLink->count = 0;
|
||||
(VOID)LOS_MemFree(m_aucSysMem0, cmdKeyLink);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellSysCmdRegister(VOID)
|
||||
{
|
||||
UINT32 i;
|
||||
UINT8 *cmdItemGroup = NULL;
|
||||
UINT32 index = sizeof(g_shellcmdAll) / sizeof(CmdItem);
|
||||
CmdItemNode *cmdItem = NULL;
|
||||
|
||||
cmdItemGroup = (UINT8 *)LOS_MemAlloc(m_aucSysMem0, index * sizeof(CmdItemNode));
|
||||
if (cmdItemGroup == NULL) {
|
||||
PRINT_ERR("[%s]System memory allocation failure!\n", __FUNCTION__);
|
||||
return (UINT32)OS_ERROR;
|
||||
}
|
||||
|
||||
for (i = 0; i < index; ++i) {
|
||||
cmdItem = (CmdItemNode *)(cmdItemGroup + i * sizeof(CmdItemNode));
|
||||
cmdItem->cmd = &g_shellcmdAll[i];
|
||||
OsCmdAscendingInsert(cmdItem);
|
||||
}
|
||||
cmdInfo.listNum += index;
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdExec(CmdParsed *cmdParsed, CHAR *cmdStr)
|
||||
{
|
||||
UINT32 ret;
|
||||
CmdCallBackFunc cmdHook = NULL;
|
||||
CmdItemNode *curCmdItem = NULL;
|
||||
UINT32 i;
|
||||
const CHAR *cmdKey = NULL;
|
||||
|
||||
if ((cmdParsed == NULL) || (cmdStr == NULL) || (strlen(cmdStr) == 0)) {
|
||||
return (UINT32)OS_ERROR;
|
||||
}
|
||||
|
||||
ret = OsCmdParse(cmdStr, cmdParsed);
|
||||
if (ret != LOS_OK) {
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(curCmdItem, &(cmdInfo.cmdList.list), CmdItemNode, list) {
|
||||
cmdKey = curCmdItem->cmd->cmdKey;
|
||||
if ((cmdParsed->cmdType == curCmdItem->cmd->cmdType) &&
|
||||
(strlen(cmdKey) == strlen(cmdParsed->cmdKeyword)) &&
|
||||
(strncmp(cmdKey, (CHAR *)(cmdParsed->cmdKeyword), strlen(cmdKey)) == 0)) {
|
||||
cmdHook = curCmdItem->cmd->cmdHook;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret = OS_ERROR;
|
||||
if (cmdHook != NULL) {
|
||||
ret = (cmdHook)(cmdParsed->paramCnt, (const CHAR **)cmdParsed->paramArray);
|
||||
}
|
||||
|
||||
OUT:
|
||||
for (i = 0; i < cmdParsed->paramCnt; i++) {
|
||||
if (cmdParsed->paramArray[i] != NULL) {
|
||||
(VOID)LOS_MemFree(m_aucSysMem0, cmdParsed->paramArray[i]);
|
||||
cmdParsed->paramArray[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return (UINT32)ret;
|
||||
}
|
||||
|
||||
ShellCB *OsGetShellCb(VOID)
|
||||
{
|
||||
return g_shellCB;
|
||||
}
|
||||
|
||||
char *OsShellGetWorkingDirtectory(VOID)
|
||||
{
|
||||
return OsGetShellCb()->shellWorkingDirectory;
|
||||
}
|
||||
|
||||
VOID OsShellCBInit(VOID)
|
||||
{
|
||||
int ret;
|
||||
ShellCB *shellCB = NULL;
|
||||
|
||||
shellCB = (ShellCB *)malloc(sizeof(ShellCB));
|
||||
if (shellCB == NULL) {
|
||||
goto ERR_OUT1;
|
||||
}
|
||||
ret = memset_s(shellCB, sizeof(ShellCB), 0, sizeof(ShellCB));
|
||||
if (ret != SH_OK) {
|
||||
goto ERR_OUT1;
|
||||
}
|
||||
|
||||
ret = (int)OsShellKeyInit(shellCB);
|
||||
if (ret != SH_OK) {
|
||||
goto ERR_OUT1;
|
||||
}
|
||||
(void)strncpy_s(shellCB->shellWorkingDirectory, PATH_MAX, "/", 2); /* 2:space for "/" */
|
||||
|
||||
g_shellCB = shellCB;
|
||||
return;
|
||||
|
||||
ERR_OUT1:
|
||||
(void)free(shellCB);
|
||||
return;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdInit(VOID)
|
||||
{
|
||||
UINT32 ret;
|
||||
LOS_ListInit(&(cmdInfo.cmdList.list));
|
||||
cmdInfo.listNum = 0;
|
||||
cmdInfo.initMagicFlag = SHELL_INIT_MAGIC_FLAG;
|
||||
ret = LOS_MuxCreate(&cmdInfo.muxLock);
|
||||
if (ret != LOS_OK) {
|
||||
PRINT_ERR("Create mutex for shell cmd info failed\n");
|
||||
return OS_ERROR;
|
||||
}
|
||||
OsShellCBInit();
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC UINT32 OsCmdItemCreate(CmdType cmdType, const CHAR *cmdKey, UINT32 paraNum, CmdCallBackFunc cmdProc)
|
||||
{
|
||||
CmdItem *cmdItem = NULL;
|
||||
CmdItemNode *cmdItemNode = NULL;
|
||||
|
||||
cmdItem = (CmdItem *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdItem));
|
||||
if (cmdItem == NULL) {
|
||||
return OS_ERRNO_SHELL_CMDREG_MEMALLOC_ERROR;
|
||||
}
|
||||
(VOID)memset_s(cmdItem, sizeof(CmdItem), '\0', sizeof(CmdItem));
|
||||
|
||||
cmdItemNode = (CmdItemNode *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdItemNode));
|
||||
if (cmdItemNode == NULL) {
|
||||
(VOID)LOS_MemFree(m_aucSysMem0, cmdItem);
|
||||
return OS_ERRNO_SHELL_CMDREG_MEMALLOC_ERROR;
|
||||
}
|
||||
(VOID)memset_s(cmdItemNode, sizeof(CmdItemNode), '\0', sizeof(CmdItemNode));
|
||||
cmdItemNode->cmd = cmdItem;
|
||||
cmdItemNode->cmd->cmdHook = cmdProc;
|
||||
cmdItemNode->cmd->paraNum = paraNum;
|
||||
cmdItemNode->cmd->cmdType = cmdType;
|
||||
cmdItemNode->cmd->cmdKey = cmdKey;
|
||||
|
||||
(VOID)LOS_MuxPend(cmdInfo.muxLock, LOS_WAIT_FOREVER);
|
||||
OsCmdAscendingInsert(cmdItemNode);
|
||||
cmdInfo.listNum++;
|
||||
(VOID)LOS_MuxPost(cmdInfo.muxLock);
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
/* open API */
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 osCmdReg(CmdType cmdType, const CHAR *cmdKey, UINT32 paraNum, CmdCallBackFunc cmdProc)
|
||||
{
|
||||
CmdItemNode *cmdItemNode = NULL;
|
||||
|
||||
(VOID)LOS_MuxPend(cmdInfo.muxLock, LOS_WAIT_FOREVER);
|
||||
if (cmdInfo.initMagicFlag != SHELL_INIT_MAGIC_FLAG) {
|
||||
(VOID)LOS_MuxPost(cmdInfo.muxLock);
|
||||
PRINT_ERR("[%s] shell is not yet initialized!\n", __FUNCTION__);
|
||||
return OS_ERRNO_SHELL_NOT_INIT;
|
||||
}
|
||||
(VOID)LOS_MuxPost(cmdInfo.muxLock);
|
||||
|
||||
if ((cmdProc == NULL) || (cmdKey == NULL) ||
|
||||
(cmdType >= CMD_TYPE_BUTT) || (strlen(cmdKey) >= CMD_KEY_LEN) || !strlen(cmdKey)) {
|
||||
return OS_ERRNO_SHELL_CMDREG_PARA_ERROR;
|
||||
}
|
||||
|
||||
if (paraNum > CMD_MAX_PARAS) {
|
||||
if (paraNum != XARGS) {
|
||||
return OS_ERRNO_SHELL_CMDREG_PARA_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (OsCmdKeyCheck(cmdKey) != TRUE) {
|
||||
return OS_ERRNO_SHELL_CMDREG_CMD_ERROR;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxPend(cmdInfo.muxLock, LOS_WAIT_FOREVER);
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(cmdItemNode, &(cmdInfo.cmdList.list), CmdItemNode, list) {
|
||||
if ((cmdType == cmdItemNode->cmd->cmdType) &&
|
||||
((strlen(cmdKey) == strlen(cmdItemNode->cmd->cmdKey)) &&
|
||||
(strncmp((CHAR *)(cmdItemNode->cmd->cmdKey), cmdKey, strlen(cmdKey)) == 0))) {
|
||||
(VOID)LOS_MuxPost(cmdInfo.muxLock);
|
||||
return OS_ERRNO_SHELL_CMDREG_CMD_EXIST;
|
||||
}
|
||||
}
|
||||
(VOID)LOS_MuxPost(cmdInfo.muxLock);
|
||||
|
||||
return OsCmdItemCreate(cmdType, cmdKey, paraNum, cmdProc);
|
||||
}
|
||||
|
||||
155
components/shell/src/base/shcmdparse.c
Executable file
155
components/shell/src/base/shcmdparse.c
Executable file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "shcmd.h"
|
||||
#include "los_memory.h"
|
||||
|
||||
|
||||
/*
|
||||
* Filter out double quote or single-quoted strings at both ends
|
||||
*/
|
||||
LITE_OS_SEC_TEXT_MINOR CHAR *OsCmdParseStrdup(const CHAR *str)
|
||||
{
|
||||
CHAR *tempStr = NULL;
|
||||
CHAR *newStr = NULL;
|
||||
|
||||
newStr = (CHAR *)LOS_MemAlloc(m_aucSysMem0, strlen(str) + 1);
|
||||
if (newStr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tempStr = newStr;
|
||||
for (; *str != '\0'; str++) {
|
||||
if ((*str == '\"') || (*str == '\'')) {
|
||||
continue;
|
||||
}
|
||||
*newStr = *str;
|
||||
newStr++;
|
||||
}
|
||||
*newStr = '\0';
|
||||
return tempStr;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdParseParaGet(CHAR **value, const CHAR *paraTokenStr)
|
||||
{
|
||||
if ((paraTokenStr == NULL) || (value == NULL)) {
|
||||
return (UINT32)OS_ERROR;
|
||||
}
|
||||
|
||||
*value = OsCmdParseStrdup(paraTokenStr);
|
||||
if (*value == NULL) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdParseOneToken(CmdParsed *cmdParsed, UINT32 index, const CHAR *token)
|
||||
{
|
||||
UINT32 ret = LOS_OK;
|
||||
UINT32 tempLen;
|
||||
|
||||
if (cmdParsed == NULL) {
|
||||
return (UINT32)OS_ERROR;
|
||||
}
|
||||
|
||||
if (index == 0) {
|
||||
if (cmdParsed->cmdType != CMD_TYPE_STD) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if ((token != NULL) && (cmdParsed->paramCnt < CMD_MAX_PARAS)) {
|
||||
tempLen = cmdParsed->paramCnt;
|
||||
ret = OsCmdParseParaGet(&(cmdParsed->paramArray[tempLen]), token);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
cmdParsed->paramCnt++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdTokenSplit(CHAR *cmdStr, CHAR split, CmdParsed *cmdParsed)
|
||||
{
|
||||
enum {
|
||||
STAT_INIT,
|
||||
STAT_TOKEN_IN,
|
||||
STAT_TOKEN_OUT
|
||||
} state = STAT_INIT;
|
||||
UINT32 count = 0;
|
||||
CHAR *p = NULL;
|
||||
CHAR *token = cmdStr;
|
||||
UINT32 ret = LOS_OK;
|
||||
BOOL quotes = FALSE;
|
||||
|
||||
if (cmdStr == NULL) {
|
||||
return (UINT32)OS_ERROR;
|
||||
}
|
||||
|
||||
for (p = cmdStr; (*p != '\0') && (ret == LOS_OK); p++) {
|
||||
if (*p == '\"') {
|
||||
SWITCH_QUOTES_STATUS(quotes);
|
||||
}
|
||||
switch (state) {
|
||||
case STAT_INIT:
|
||||
case STAT_TOKEN_IN:
|
||||
if ((*p == split) && QUOTES_STATUS_CLOSE(quotes)) {
|
||||
*p = '\0';
|
||||
ret = OsCmdParseOneToken(cmdParsed, count++, token);
|
||||
state = STAT_TOKEN_OUT;
|
||||
}
|
||||
break;
|
||||
case STAT_TOKEN_OUT:
|
||||
if (*p != split) {
|
||||
token = p;
|
||||
state = STAT_TOKEN_IN;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (((ret == LOS_OK) && (state == STAT_TOKEN_IN)) || (state == STAT_INIT)) {
|
||||
ret = OsCmdParseOneToken(cmdParsed, count, token);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdParse(CHAR *cmdStr, CmdParsed *cmdParsed)
|
||||
{
|
||||
if ((cmdStr == NULL) || (cmdParsed == NULL) || (strlen(cmdStr) == 0)) {
|
||||
return (UINT32)OS_ERROR;
|
||||
}
|
||||
return OsCmdTokenSplit(cmdStr, ' ', cmdParsed);
|
||||
}
|
||||
|
||||
295
components/shell/src/base/shmsg.c
Executable file
295
components/shell/src/base/shmsg.c
Executable file
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "shmsg.h"
|
||||
#include "securec.h"
|
||||
#include "shcmd.h"
|
||||
#include "show.h"
|
||||
#if (LOSCFG_USE_SHELL == 1)
|
||||
#include "uart.h"
|
||||
#endif
|
||||
#include "los_event.h"
|
||||
#include "los_task.h"
|
||||
|
||||
EVENT_CB_S g_shellInputEvent;
|
||||
#define SHELL_CMD_MAX_SIZE 64
|
||||
|
||||
#define VISIABLE_CHAR(ch) ((ch) > 0x1F && (ch) < 0x7F)
|
||||
|
||||
UINT32 ShellMsgTypeGet(CmdParsed *cmdParsed, const CHAR *cmdType)
|
||||
{
|
||||
CmdItemNode *curCmdItem = (CmdItemNode *)NULL;
|
||||
UINT32 len;
|
||||
UINT32 minLen;
|
||||
CmdModInfo *cmdInfo = OsCmdInfoGet();
|
||||
|
||||
if ((cmdParsed == NULL) || (cmdType == NULL)) {
|
||||
return OS_INVALID;
|
||||
}
|
||||
|
||||
len = strlen(cmdType);
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(curCmdItem, &(cmdInfo->cmdList.list), CmdItemNode, list) {
|
||||
if ((len == strlen(curCmdItem->cmd->cmdKey)) &&
|
||||
(strncmp((CHAR *)(curCmdItem->cmd->cmdKey), cmdType, len) == 0)) {
|
||||
minLen = (len < CMD_KEY_LEN) ? len : CMD_KEY_LEN;
|
||||
(VOID)memcpy_s((CHAR *)(cmdParsed->cmdKeyword), CMD_KEY_LEN, cmdType, minLen);
|
||||
cmdParsed->cmdType = curCmdItem->cmd->cmdType;
|
||||
return LOS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return OS_INVALID;
|
||||
}
|
||||
|
||||
CHAR *GetCmdName(const CHAR *cmdline, UINT32 len)
|
||||
{
|
||||
UINT32 loop;
|
||||
const CHAR *tmpStr = NULL;
|
||||
BOOL quotes = FALSE;
|
||||
CHAR *cmdName = NULL;
|
||||
if (cmdline == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cmdName = (CHAR *)malloc(len + 1);
|
||||
if (cmdName == NULL) {
|
||||
PRINTK("malloc failure in %s[%d]\n", __FUNCTION__, __LINE__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Scan the 'cmdline' string for command */
|
||||
/* Notice: Command string must not have any special name */
|
||||
for (tmpStr = cmdline, loop = 0; (*tmpStr != '\0') && (loop < len); ) {
|
||||
/* If reach a double quotes, switch the quotes matching status */
|
||||
if (*tmpStr == '\"') {
|
||||
SWITCH_QUOTES_STATUS(quotes);
|
||||
/* Ignore the double quote charactor itself */
|
||||
tmpStr++;
|
||||
continue;
|
||||
}
|
||||
/* If detected a space which the quotes matching status is false */
|
||||
/* which said has detected the first space for seperator, finish this scan operation */
|
||||
if ((*tmpStr == ' ') && (QUOTES_STATUS_CLOSE(quotes))) {
|
||||
break;
|
||||
}
|
||||
cmdName[loop] = *tmpStr++;
|
||||
loop++;
|
||||
}
|
||||
cmdName[loop] = '\0';
|
||||
|
||||
return cmdName;
|
||||
}
|
||||
|
||||
INT32 ShellCmdExec(const CHAR *msgName, const CHAR *cmdString)
|
||||
{
|
||||
UINT32 uintRet;
|
||||
errno_t err;
|
||||
CmdParsed cmdParsed;
|
||||
|
||||
if (msgName == NULL || cmdString == NULL) {
|
||||
return -EFAULT;
|
||||
}
|
||||
err = memset_s(&cmdParsed, sizeof(CmdParsed), 0, sizeof(CmdParsed));
|
||||
if (err != EOK) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
uintRet = ShellMsgTypeGet(&cmdParsed, msgName);
|
||||
if (uintRet != LOS_OK) {
|
||||
PRINTK("%s:command not found\n", msgName);
|
||||
return -EFAULT;
|
||||
} else {
|
||||
(VOID)OsCmdExec(&cmdParsed, (CHAR *)cmdString);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT32 PreHandleCmdline(const CHAR *input, CHAR **output, UINT32 *outputlen)
|
||||
{
|
||||
UINT32 shiftLen;
|
||||
UINT32 ret;
|
||||
const CHAR *cmdBuf = input;
|
||||
UINT32 cmdBufLen = strlen(cmdBuf);
|
||||
if ((cmdBufLen + 1) > SHELL_CMD_MAX_SIZE) {
|
||||
return SH_NOK;
|
||||
}
|
||||
CHAR *shiftStr = (CHAR *)malloc(cmdBufLen + 1);
|
||||
|
||||
if (shiftStr == NULL) {
|
||||
PRINTK("malloc failure in %s[%d]\n", __FUNCTION__, __LINE__);
|
||||
return SH_NOK;
|
||||
}
|
||||
(VOID)memset_s(shiftStr, cmdBufLen + 1, 0, cmdBufLen + 1);
|
||||
|
||||
/* Call function 'OsCmdKeyShift' to squeeze and clear useless or overmuch space if string buffer */
|
||||
ret = OsCmdKeyShift(cmdBuf, shiftStr, cmdBufLen + 1);
|
||||
shiftLen = strlen(shiftStr);
|
||||
if ((ret != SH_OK) || (shiftLen == 0)) {
|
||||
ret = SH_NOK;
|
||||
goto END_FREE_SHIFTSTR;
|
||||
}
|
||||
*output = shiftStr;
|
||||
*outputlen = shiftLen;
|
||||
|
||||
ret = SH_OK;
|
||||
goto END;
|
||||
|
||||
END_FREE_SHIFTSTR:
|
||||
free(shiftStr);
|
||||
END:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static VOID ParseAndExecCmdline(CmdParsed *cmdParsed, const CHAR *cmdline, UINT32 len)
|
||||
{
|
||||
INT32 i;
|
||||
UINT32 ret;
|
||||
CHAR *cmdlineOrigin = NULL;
|
||||
CHAR *cmdName = NULL;
|
||||
|
||||
cmdlineOrigin = strdup(cmdline);
|
||||
if (cmdlineOrigin == NULL) {
|
||||
PRINTK("malloc failure in %s[%d]\n", __FUNCTION__, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
cmdName = GetCmdName(cmdline, len);
|
||||
if (cmdName == NULL) {
|
||||
free(cmdlineOrigin);
|
||||
PRINTK("malloc failure in %s[%d]\n", __FUNCTION__, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = OsCmdParse((CHAR *)cmdline, cmdParsed);
|
||||
if (ret != SH_OK) {
|
||||
PRINTK("cmd parse failure in %s[%d]\n", __FUNCTION__, __LINE__);
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
(VOID)ShellCmdExec(cmdName, cmdlineOrigin);
|
||||
|
||||
OUT:
|
||||
for (i = 0; i < cmdParsed->paramCnt; i++) {
|
||||
if (cmdParsed->paramArray[i] != NULL) {
|
||||
free(cmdParsed->paramArray[i]);
|
||||
cmdParsed->paramArray[i] = NULL;
|
||||
}
|
||||
}
|
||||
free(cmdName);
|
||||
free(cmdlineOrigin);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID ExecCmdline(const CHAR *cmdline)
|
||||
{
|
||||
UINT32 ret;
|
||||
CHAR *output = NULL;
|
||||
UINT32 outputlen;
|
||||
CmdParsed cmdParsed;
|
||||
|
||||
if (cmdline == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
OsShellInit(0);
|
||||
|
||||
/* strip out unnecessary characters */
|
||||
ret = PreHandleCmdline(cmdline, &output, &outputlen);
|
||||
if (ret == SH_NOK) {
|
||||
return;
|
||||
}
|
||||
|
||||
(VOID)memset_s(&cmdParsed, sizeof(CmdParsed), 0, sizeof(CmdParsed));
|
||||
ParseAndExecCmdline(&cmdParsed, output, outputlen);
|
||||
free(output);
|
||||
}
|
||||
|
||||
#if (LOSCFG_USE_SHELL == 1)
|
||||
VOID ShellTaskEntry(VOID)
|
||||
{
|
||||
CHAR buf[SHELL_CMD_MAX_SIZE] = {0};
|
||||
CHAR *ptr = buf;
|
||||
PRINTK("OHOS # ");
|
||||
while (1) {
|
||||
(VOID)LOS_EventRead(&g_shellInputEvent, 0x1, LOS_WAITMODE_AND | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER);
|
||||
while ((*ptr = (UINT8)UartGetc()) != 0 && *ptr != 13) {
|
||||
if (*ptr == '\x03') { /* ctrl + c */
|
||||
PRINTK("^C\n\rOHOS # ", *ptr);
|
||||
ptr = buf;
|
||||
break;
|
||||
}
|
||||
if (!VISIABLE_CHAR(*ptr)) {
|
||||
break;
|
||||
}
|
||||
PRINTK("%c", *ptr);
|
||||
if ((ptr - buf) == (sizeof(buf) - 1)) {
|
||||
break;
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
if (ptr != buf) {
|
||||
if (*ptr == 13 || ((ptr - buf) == (sizeof(buf) - 1))) {
|
||||
*ptr = '\0';
|
||||
ptr = buf;
|
||||
PRINTK("\n\r");
|
||||
ExecCmdline(buf);
|
||||
PRINTK("OHOS # ");
|
||||
}
|
||||
} else if (*ptr == 13) {
|
||||
PRINTK("\n\rOHOS # ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 LosShellInit(VOID)
|
||||
{
|
||||
UINT32 ret;
|
||||
UINT32 taskID1, taskID2;
|
||||
TSK_INIT_PARAM_S task1 = { 0 };
|
||||
|
||||
ret = LOS_EventInit(&g_shellInputEvent);
|
||||
if (ret != LOS_OK) {
|
||||
PRINTK("Init shellInputEvent failed! ERROR: 0x%x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
task1.pfnTaskEntry = (TSK_ENTRY_FUNC)ShellTaskEntry;
|
||||
task1.uwStackSize = 0x1000;
|
||||
task1.pcName = "ShellTaskEntry";
|
||||
task1.usTaskPrio = LOSCFG_SHELL_PRIO;
|
||||
ret = LOS_TaskCreate(&taskID1, &task1);
|
||||
if (ret != LOS_OK) {
|
||||
PRINTK("Create Shell Task failed! ERROR: 0x%x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
62
components/shell/src/base/show.c
Executable file
62
components/shell/src/base/show.c
Executable file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "show.h"
|
||||
#include "shmsg.h"
|
||||
#include "shcmd.h"
|
||||
|
||||
|
||||
STATIC BOOL g_shellSourceFlag = FALSE;
|
||||
|
||||
STATIC UINT32 OsShellCmdInit(VOID)
|
||||
{
|
||||
UINT32 ret = OsCmdInit();
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return OsShellSysCmdRegister();
|
||||
}
|
||||
|
||||
UINT32 OsShellInit(INT32 consoleId)
|
||||
{
|
||||
if (g_shellSourceFlag == FALSE) {
|
||||
UINT32 ret = OsShellCmdInit();
|
||||
if (ret == LOS_OK) {
|
||||
g_shellSourceFlag = TRUE;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
56
components/shell/src/cmds/date_shell.c
Executable file
56
components/shell/src/cmds/date_shell.c
Executable file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "shcmd.h"
|
||||
#include "shell.h"
|
||||
#include "stdlib.h"
|
||||
#include "sys/time.h"
|
||||
#include "sys/stat.h"
|
||||
#include "securec.h"
|
||||
|
||||
#define DATE_ERR (-1)
|
||||
#define DATE_OK 0
|
||||
|
||||
INT32 OsShellCmdDate(INT32 argc, const CHAR **argv)
|
||||
{
|
||||
struct timeval nowTime;
|
||||
|
||||
if (argc == 1) { /* 1:count of parameters */
|
||||
if (gettimeofday(&nowTime, NULL)) {
|
||||
return DATE_ERR;
|
||||
}
|
||||
PRINTK("%s\n", ctime(&nowTime.tv_sec));
|
||||
return DATE_OK;
|
||||
}
|
||||
|
||||
return DATE_OK;
|
||||
}
|
||||
|
||||
268
components/shell/src/cmds/fullpath.c
Executable file
268
components/shell/src/cmds/fullpath.c
Executable file
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "stdio.h"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include "errno.h"
|
||||
#include "limits.h"
|
||||
#include "shell.h"
|
||||
#include "show.h"
|
||||
|
||||
#define TEMP_PATH_MAX (PATH_MAX + SHOW_MAX_LEN)
|
||||
|
||||
static unsigned int VfsStrnlen(const char *str, size_t maxlen)
|
||||
{
|
||||
const char *p = NULL;
|
||||
|
||||
for (p = str; ((maxlen-- != 0) && (*p != '\0')); ++p) {}
|
||||
|
||||
return p - str;
|
||||
}
|
||||
|
||||
/* abandon the redundant '/' in the path, only keep one. */
|
||||
static char *StrPath(char *path)
|
||||
{
|
||||
char *dest = path;
|
||||
char *src = path;
|
||||
|
||||
while (*src != '\0') {
|
||||
if (*src == '/') {
|
||||
*dest++ = *src++;
|
||||
while (*src == '/') {
|
||||
src++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
*dest++ = *src++;
|
||||
}
|
||||
*dest = '\0';
|
||||
return path;
|
||||
}
|
||||
|
||||
static void StrRemovePathEndSlash(char *dest, const char *fullpath)
|
||||
{
|
||||
if ((*dest == '.') && (*(dest - 1) == '/')) {
|
||||
*dest = '\0';
|
||||
dest--;
|
||||
}
|
||||
if ((dest != fullpath) && (*dest == '/')) {
|
||||
*dest = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
static char *StrNormalizePath(char *fullpath)
|
||||
{
|
||||
char *dest = fullpath;
|
||||
char *src = fullpath;
|
||||
|
||||
/* 2: The position of the path character: / and the end character /0 */
|
||||
while (*src != '\0') {
|
||||
if (*src == '.') {
|
||||
if (*(src + 1) == '/') {
|
||||
src += 2; /* 2, sizeof "./" */
|
||||
continue;
|
||||
} else if (*(src + 1) == '.') {
|
||||
if ((*(src + 2) == '/') || (*(src + 2) == '\0')) { /* 2, 2, offset to check */
|
||||
src += 2; /* 2, sizeof offset */
|
||||
} else {
|
||||
while ((*src != '\0') && (*src != '/')) {
|
||||
*dest++ = *src++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
*dest++ = *src++;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
*dest++ = *src++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((dest - 1) != fullpath) {
|
||||
dest--;
|
||||
}
|
||||
|
||||
while ((dest > fullpath) && (*(dest - 1) != '/')) {
|
||||
dest--;
|
||||
}
|
||||
|
||||
if (*src == '/') {
|
||||
src++;
|
||||
}
|
||||
}
|
||||
|
||||
*dest = '\0';
|
||||
|
||||
/* remove '/' in the end of path if exist */
|
||||
|
||||
dest--;
|
||||
|
||||
StrRemovePathEndSlash(dest, fullpath);
|
||||
return dest;
|
||||
}
|
||||
|
||||
static int VfsNormalizePathParameCheck(const char *filename, char **pathname)
|
||||
{
|
||||
int namelen;
|
||||
char *name = NULL;
|
||||
|
||||
if (pathname == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* check parameters */
|
||||
|
||||
if (filename == NULL) {
|
||||
*pathname = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
namelen = VfsStrnlen(filename, PATH_MAX);
|
||||
if (!namelen) {
|
||||
*pathname = NULL;
|
||||
return -EINVAL;
|
||||
} else if (namelen >= PATH_MAX) {
|
||||
*pathname = NULL;
|
||||
return -ENAMETOOLONG;
|
||||
}
|
||||
|
||||
for (name = (char *)filename + namelen; ((name != filename) && (*name != '/')); name--) {
|
||||
if (strlen(name) > NAME_MAX) {
|
||||
*pathname = NULL;
|
||||
return -ENAMETOOLONG;
|
||||
}
|
||||
}
|
||||
|
||||
return namelen;
|
||||
}
|
||||
|
||||
static char *VfsNotAbsolutePath(const char *directory, const char *filename, char **pathname, int namelen)
|
||||
{
|
||||
int ret;
|
||||
char *fullpath = NULL;
|
||||
|
||||
/* 2: The position of the path character: / and the end character /0 */
|
||||
|
||||
if ((namelen > 1) && (filename[0] == '.') && (filename[1] == '/')) {
|
||||
filename += 2; /* 2, sizeof "./" */
|
||||
}
|
||||
|
||||
fullpath = (char *)malloc(strlen(directory) + namelen + 2);
|
||||
if (fullpath == NULL) {
|
||||
*pathname = NULL;
|
||||
SetErrno(ENOMEM);
|
||||
return (char *)NULL;
|
||||
}
|
||||
|
||||
/* 2, sizeof "./", join path and file name */
|
||||
ret = snprintf_s(fullpath, strlen(directory) + namelen + 2, strlen(directory) + namelen + 1,
|
||||
"%s/%s", directory, filename);
|
||||
if (ret < 0) {
|
||||
*pathname = NULL;
|
||||
free(fullpath);
|
||||
SetErrno(ENAMETOOLONG);
|
||||
return (char *)NULL;
|
||||
}
|
||||
|
||||
return fullpath;
|
||||
}
|
||||
|
||||
static char *VfsNormalizeFullpath(const char *directory, const char *filename, char **pathname, int namelen)
|
||||
{
|
||||
char *fullpath = NULL;
|
||||
|
||||
if (filename[0] != '/') {
|
||||
/* not a absolute path */
|
||||
|
||||
fullpath = VfsNotAbsolutePath(directory, filename, pathname, namelen);
|
||||
if (fullpath == NULL) {
|
||||
return (char *)NULL;
|
||||
}
|
||||
} else {
|
||||
/* it's a absolute path, use it directly */
|
||||
|
||||
fullpath = strdup(filename); /* copy string */
|
||||
if (fullpath == NULL) {
|
||||
*pathname = NULL;
|
||||
SetErrno(ENOMEM);
|
||||
return (char *)NULL;
|
||||
}
|
||||
if (filename[1] == '/') {
|
||||
*pathname = NULL;
|
||||
free(fullpath);
|
||||
SetErrno(EINVAL);
|
||||
return (char *)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return fullpath;
|
||||
}
|
||||
|
||||
int VfsNormalizePath(const char *directory, const char *filename, char **pathname)
|
||||
{
|
||||
char *fullpath = NULL;
|
||||
int namelen;
|
||||
|
||||
namelen = VfsNormalizePathParameCheck(filename, pathname);
|
||||
if (namelen < 0) {
|
||||
return namelen;
|
||||
}
|
||||
|
||||
if ((directory == NULL) && (filename[0] != '/')) {
|
||||
PRINT_ERR("NO_WORKING_DIR\n");
|
||||
*pathname = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* 2, The position of the path character: / and the end character /0 */
|
||||
if ((filename[0] != '/') && (strlen(directory) + namelen + 2 > TEMP_PATH_MAX)) {
|
||||
return -ENAMETOOLONG;
|
||||
}
|
||||
|
||||
fullpath = VfsNormalizeFullpath(directory, filename, pathname, namelen);
|
||||
if (fullpath == NULL) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
(void)StrPath(fullpath);
|
||||
(void)StrNormalizePath(fullpath);
|
||||
if (strlen(fullpath) >= PATH_MAX) {
|
||||
*pathname = NULL;
|
||||
free(fullpath);
|
||||
return -ENAMETOOLONG;
|
||||
}
|
||||
|
||||
*pathname = fullpath;
|
||||
return 0;
|
||||
}
|
||||
|
||||
80
components/shell/src/cmds/mempt_shellcmd.c
Executable file
80
components/shell/src/cmds/mempt_shellcmd.c
Executable file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "stdlib.h"
|
||||
#include "shcmd.h"
|
||||
#include "shell.h"
|
||||
|
||||
#define MEM_SIZE_1K 0x400
|
||||
#define MEM_SIZE_1M 0x100000
|
||||
|
||||
#define MEM_SIZE_TO_KB(size) (((size) + (MEM_SIZE_1K >> 1)) / MEM_SIZE_1K)
|
||||
#define MEM_SIZE_TO_MB(size) (((size) + (MEM_SIZE_1M >> 1)) / MEM_SIZE_1M)
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR STATIC UINT32 OsShellCmdFreeInfo(INT32 argc, const CHAR *argv[])
|
||||
{
|
||||
UINT32 memUsed = LOS_MemTotalUsedGet(m_aucSysMem0);
|
||||
UINT32 totalMem = LOS_MemPoolSizeGet(m_aucSysMem0);
|
||||
UINT32 freeMem = totalMem - memUsed;
|
||||
|
||||
if ((argc == 0) ||
|
||||
((argc == 1) && (strcmp(argv[0], "-k") == 0)) ||
|
||||
((argc == 1) && (strcmp(argv[0], "-m") == 0))) {
|
||||
PRINTK("\r\n total used free\n");
|
||||
}
|
||||
|
||||
if ((argc == 1) && (strcmp(argv[0], "-k") == 0)) {
|
||||
PRINTK("Mem: %-9u %-10u %-10u\n", MEM_SIZE_TO_KB(totalMem), MEM_SIZE_TO_KB(memUsed),
|
||||
MEM_SIZE_TO_KB(freeMem));
|
||||
} else if ((argc == 1) && (strcmp(argv[0], "-m") == 0)) {
|
||||
PRINTK("Mem: %-9u %-10u %-10u\n", MEM_SIZE_TO_MB(totalMem), MEM_SIZE_TO_MB(memUsed),
|
||||
MEM_SIZE_TO_MB(freeMem));
|
||||
} else if (argc == 0) {
|
||||
PRINTK("Mem: %-9u %-10u %-10u\n", totalMem, memUsed, freeMem);
|
||||
} else {
|
||||
PRINTK("\nUsage: free or free [-k/-m]\n");
|
||||
return OS_ERROR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdFree(INT32 argc, const CHAR *argv[])
|
||||
{
|
||||
if (argc > 1) {
|
||||
PRINTK("\nUsage: free or free [-k/-m]\n");
|
||||
return OS_ERROR;
|
||||
}
|
||||
if (OsShellCmdFreeInfo(argc, argv) != 0) {
|
||||
return OS_ERROR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
62
components/shell/src/cmds/shell_shellcmd.c
Executable file
62
components/shell/src/cmds/shell_shellcmd.c
Executable file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "shcmd.h"
|
||||
|
||||
#define DEFAULT_SCREEN_WIDTH 80
|
||||
#define MAX_CMD_KEY_WIDTH 8
|
||||
#define CMD_ITEM_PER_LINE (DEFAULT_SCREEN_WIDTH / (MAX_CMD_KEY_WIDTH + 1))
|
||||
|
||||
INT32 OsShellCmdHelp(INT32 argc, const CHAR **argv)
|
||||
{
|
||||
UINT32 loop = 0;
|
||||
CmdItemNode *curCmdItem = NULL;
|
||||
CmdModInfo *cmdInfo = OsCmdInfoGet();
|
||||
|
||||
(VOID)argv;
|
||||
if (argc > 0) {
|
||||
PRINTK("\nUsage: help\n");
|
||||
return OS_ERROR;
|
||||
}
|
||||
|
||||
PRINTK("*******************shell commands:*************************\n");
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(curCmdItem, &(cmdInfo->cmdList.list), CmdItemNode, list) {
|
||||
if ((loop % CMD_ITEM_PER_LINE) == 0) { /* just align print */
|
||||
PRINTK("\n");
|
||||
}
|
||||
PRINTK("%-8s ", curCmdItem->cmd->cmdKey);
|
||||
|
||||
loop++;
|
||||
}
|
||||
|
||||
PRINTK("\n");
|
||||
return 0;
|
||||
}
|
||||
156
components/shell/src/cmds/task_shellcmd.c
Executable file
156
components/shell/src/cmds/task_shellcmd.c
Executable file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "stdlib.h"
|
||||
#include "los_config.h"
|
||||
#include "los_task.h"
|
||||
#include "los_sem.h"
|
||||
#include "shcmd.h"
|
||||
#include "shell.h"
|
||||
|
||||
#define OS_INVALID_SEM_ID 0xFFFFFFFF
|
||||
#define OS_ALL_TASK_MASK 0xFFFFFFFF
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR STATIC VOID OsShellCmdTskInfoTitle(VOID)
|
||||
{
|
||||
PRINTK("Name TaskEntryAddr TID ");
|
||||
|
||||
PRINTK("Priority Status "
|
||||
#if (LOSCFG_TASK_MEM_USED == 1)
|
||||
"AllocSize "
|
||||
#endif
|
||||
"StackSize StackPoint TopOfStack");
|
||||
|
||||
PRINTK("\n");
|
||||
PRINTK("---- ------------- --- ");
|
||||
PRINTK("-------- -------- "
|
||||
#if (LOSCFG_TASK_MEM_USED == 1)
|
||||
"--------- "
|
||||
#endif
|
||||
"--------- ---------- ----------");
|
||||
PRINTK("\n");
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR STATIC INLINE UINT32 OsGetSemID(const LosTaskCB *taskCB)
|
||||
{
|
||||
UINT32 semId = OS_INVALID_SEM_ID;
|
||||
|
||||
if (taskCB->taskSem != NULL) {
|
||||
semId = ((LosSemCB *)taskCB->taskSem)->semID;
|
||||
}
|
||||
|
||||
return semId;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR STATIC VOID OsShellCmdTskInfoData(const LosTaskCB *allTaskArray)
|
||||
{
|
||||
const LosTaskCB *taskCB = NULL;
|
||||
UINT32 loop;
|
||||
|
||||
#if (LOSCFG_TASK_MEM_USED == 1)
|
||||
UINT32 arraySize = sizeof(UINT32) * (LOSCFG_BASE_CORE_TSK_LIMIT + 1);
|
||||
UINT32 *getUsedSizeArray = (UINT32 *)LOS_MemAlloc(m_aucSysMem0, arraySize);
|
||||
if (getUsedSizeArray == NULL) {
|
||||
PRINTK("Memory is not enough to save task info!\n");
|
||||
return;
|
||||
}
|
||||
(VOID)memset_s(getUsedSizeArray, arraySize, 0, arraySize);
|
||||
OsTaskMemUsed(m_aucSysMem0, getUsedSizeArray, (LOSCFG_BASE_CORE_TSK_LIMIT + 1));
|
||||
#endif
|
||||
|
||||
for (loop = 0; loop < g_taskMaxNum; ++loop) {
|
||||
taskCB = allTaskArray + loop;
|
||||
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PRINTK("%-23s%-20p0x%-5x", taskCB->taskName, taskCB->taskEntry, taskCB->taskID);
|
||||
#if (LOSCFG_TASK_MEM_USED == 1)
|
||||
PRINTK("%-11u%-13s0x%-11x 0x%-11x 0x%-8x 0x%-10x ", taskCB->priority,
|
||||
OsConvertTskStatus(taskCB->taskStatus), getUsedSizeArray[loop], taskCB->stackSize,
|
||||
taskCB->stackPointer, taskCB->topOfStack);
|
||||
#else
|
||||
PRINTK("%-11u%-13s0x%-11x 0x%-8x 0x%-10x ", taskCB->priority,
|
||||
OsConvertTskStatus(taskCB->taskStatus), taskCB->stackSize,
|
||||
taskCB->stackPointer, taskCB->topOfStack);
|
||||
#endif
|
||||
PRINTK("\n");
|
||||
}
|
||||
#if (LOSCFG_TASK_MEM_USED == 1)
|
||||
(VOID)LOS_MemFree(m_aucSysMem0, getUsedSizeArray);
|
||||
#endif
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdTskInfoGet(UINT32 taskId)
|
||||
{
|
||||
BOOL backupFlag = TRUE;
|
||||
UINT32 size;
|
||||
LosTaskCB *tcbArray = NULL;
|
||||
INT32 ret;
|
||||
|
||||
if (taskId == OS_ALL_TASK_MASK) {
|
||||
size = g_taskMaxNum * sizeof(LosTaskCB);
|
||||
tcbArray = (LosTaskCB *)LOS_MemAlloc(m_aucSysMem0, size);
|
||||
if (tcbArray == NULL) {
|
||||
PRINTK("Memory is not enough to save task info!\n");
|
||||
tcbArray = g_taskCBArray;
|
||||
backupFlag = FALSE;
|
||||
}
|
||||
if (backupFlag == TRUE) {
|
||||
ret = memcpy_s(tcbArray, size, g_taskCBArray, size);
|
||||
if (ret != 0) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
}
|
||||
|
||||
OsShellCmdTskInfoTitle();
|
||||
OsShellCmdTskInfoData(tcbArray);
|
||||
|
||||
if (backupFlag == TRUE) {
|
||||
(VOID)LOS_MemFree(m_aucSysMem0, tcbArray);
|
||||
}
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
INT32 OsShellCmdDumpTask(INT32 argc, const CHAR **argv)
|
||||
{
|
||||
size_t taskId = OS_ALL_TASK_MASK;
|
||||
|
||||
if (argc < 1) {
|
||||
return OsShellCmdTskInfoGet((UINT32)taskId);
|
||||
} else {
|
||||
PRINTK("\nUsage: task\n");
|
||||
return OS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
957
components/shell/src/cmds/vfs_shellcmd.c
Executable file
957
components/shell/src/cmds/vfs_shellcmd.c
Executable file
@@ -0,0 +1,957 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_config.h"
|
||||
|
||||
#include "los_task.h"
|
||||
#include "shell.h"
|
||||
#include "sys/stat.h"
|
||||
#include "stdlib.h"
|
||||
#include "unistd.h"
|
||||
#include "fcntl.h"
|
||||
#include "stdio.h"
|
||||
#include "pthread.h"
|
||||
|
||||
#include "shcmd.h"
|
||||
#include "securec.h"
|
||||
#include "show.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define VFS_ERROR OS_ERROR
|
||||
#define SHOW_MAX_LEN CMD_MAX_LEN
|
||||
#define TEMP_PATH_MAX (PATH_MAX + SHOW_MAX_LEN)
|
||||
|
||||
typedef enum {
|
||||
RM_RECURSIVER,
|
||||
RM_FILE,
|
||||
RM_DIR,
|
||||
CP_FILE,
|
||||
CP_COUNT
|
||||
} wildcard_type;
|
||||
|
||||
#define ERROR_OUT_IF(condition, message_function, handler) \
|
||||
do { \
|
||||
if (condition) { \
|
||||
message_function; \
|
||||
handler; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
int OsShellCmdDoChdir(const char *path)
|
||||
{
|
||||
char *fullpath = NULL;
|
||||
char *fullpathBak = NULL;
|
||||
DIR *dirent = NULL;
|
||||
int ret;
|
||||
char *shellWorkingDirectory = OsShellGetWorkingDirtectory();
|
||||
if (shellWorkingDirectory == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (path == NULL) {
|
||||
LOS_TaskLock();
|
||||
PRINTK("%s\n", shellWorkingDirectory);
|
||||
LOS_TaskUnlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
ERROR_OUT_IF(strlen(path) > PATH_MAX, SetErr(ENOTDIR, "cd error"), return -1);
|
||||
|
||||
ret = VfsNormalizePath(shellWorkingDirectory, path, &fullpath);
|
||||
ERROR_OUT_IF(ret < 0, SetErr(-ret, "cd error"), return -1);
|
||||
|
||||
fullpathBak = fullpath;
|
||||
dirent = opendir(fullpath);
|
||||
if (dirent == NULL) {
|
||||
free(fullpathBak);
|
||||
/* this is a not exist directory */
|
||||
PRINTK("no such file or directory\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* close directory stream */
|
||||
(void)closedir(dirent);
|
||||
|
||||
/* copy full path to working directory */
|
||||
LOS_TaskLock();
|
||||
ret = strncpy_s(shellWorkingDirectory, PATH_MAX, fullpath, strlen(fullpath));
|
||||
if (ret != EOK) {
|
||||
free(fullpathBak);
|
||||
LOS_TaskUnlock();
|
||||
return -1;
|
||||
}
|
||||
LOS_TaskUnlock();
|
||||
/* release normalize directory path name */
|
||||
|
||||
free(fullpathBak);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *OsLsGetFullpath(const char *path, struct dirent *pdirent)
|
||||
{
|
||||
char *fullpath = NULL;
|
||||
int ret;
|
||||
|
||||
if (path[1] != '\0') {
|
||||
fullpath = (char *)malloc(strlen(path) + strlen(pdirent->d_name) + 2);
|
||||
if (fullpath == NULL) {
|
||||
goto exit_with_nomem;
|
||||
}
|
||||
|
||||
ret = snprintf_s(fullpath, strlen(path) + strlen(pdirent->d_name) + 2,
|
||||
strlen(path) + strlen(pdirent->d_name) + 1, "%s/%s", path, pdirent->d_name);
|
||||
if (ret < 0) {
|
||||
free(fullpath);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
fullpath = (char *)malloc(strlen(pdirent->d_name) + 2);
|
||||
if (fullpath == NULL) {
|
||||
goto exit_with_nomem;
|
||||
}
|
||||
|
||||
ret = snprintf_s(fullpath, strlen(pdirent->d_name) + 2, strlen(pdirent->d_name) + 1,
|
||||
"/%s", pdirent->d_name);
|
||||
if (ret < 0) {
|
||||
free(fullpath);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return fullpath;
|
||||
exit_with_nomem:
|
||||
return (char *)NULL;
|
||||
}
|
||||
|
||||
void OsLs(const char *pathname)
|
||||
{
|
||||
struct dirent *pdirent = NULL;
|
||||
char *path = NULL;
|
||||
char *fullpath = NULL;
|
||||
char *fullpathBak = NULL;
|
||||
int ret;
|
||||
struct stat statInfo = { 0 };
|
||||
DIR *d = NULL;
|
||||
|
||||
/* list all directory and file */
|
||||
if (pathname == NULL) {
|
||||
path = strdup("/");
|
||||
if (path == NULL) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
ret = VfsNormalizePath(NULL, pathname, &path);
|
||||
if (ret < 0) {
|
||||
SetErrno(-ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
d = opendir(path);
|
||||
if (d == NULL) {
|
||||
PRINT_ERR("No such directory = %s\n", path);
|
||||
} else {
|
||||
PRINTK("Directory %s:\n", path);
|
||||
do {
|
||||
pdirent = readdir(d);
|
||||
if (pdirent != NULL) {
|
||||
(void)memset_s(&statInfo, sizeof(struct stat), 0, sizeof(struct stat));
|
||||
fullpath = OsLsGetFullpath(path, pdirent);
|
||||
if (fullpath == NULL) {
|
||||
free(path);
|
||||
(void)closedir(d);
|
||||
return;
|
||||
}
|
||||
|
||||
fullpathBak = fullpath;
|
||||
if (stat(fullpath, &statInfo) == 0) {
|
||||
PRINTK("%-20s", pdirent->d_name);
|
||||
if (S_ISDIR(statInfo.st_mode)) {
|
||||
PRINTK(" %-25s\n", "<DIR>");
|
||||
} else {
|
||||
PRINTK(" %-25lu\n", statInfo.st_size);
|
||||
}
|
||||
} else {
|
||||
PRINTK("BAD file: %s\n", pdirent->d_name);
|
||||
}
|
||||
free(fullpathBak);
|
||||
}
|
||||
} while (pdirent != NULL);
|
||||
|
||||
(void)closedir(d);
|
||||
}
|
||||
}
|
||||
|
||||
int OsShellCmdLs(int argc, const char **argv)
|
||||
{
|
||||
char *fullpath = NULL;
|
||||
const char *filename = NULL;
|
||||
int ret;
|
||||
char *shellWorkingDirectory = OsShellGetWorkingDirtectory();
|
||||
if (shellWorkingDirectory == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ERROR_OUT_IF(argc > 1, PRINTK("ls or ls [DIRECTORY]\n"), return -1);
|
||||
|
||||
if (argc == 0) {
|
||||
OsLs(shellWorkingDirectory);
|
||||
return 0;
|
||||
}
|
||||
|
||||
filename = argv[0];
|
||||
ret = VfsNormalizePath(shellWorkingDirectory, filename, &fullpath);
|
||||
ERROR_OUT_IF(ret < 0, SetErr(-ret, "ls error"), return -1);
|
||||
|
||||
OsLs(fullpath);
|
||||
free(fullpath);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OsShellCmdCd(int argc, const char **argv)
|
||||
{
|
||||
if (argc == 0) {
|
||||
(void)OsShellCmdDoChdir("/");
|
||||
return 0;
|
||||
}
|
||||
|
||||
OsShellCmdDoChdir(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CAT_BUF_SIZE 512
|
||||
#define CAT_TASK_PRIORITY 10
|
||||
#define CAT_TASK_STACK_SIZE 0x3000
|
||||
pthread_mutex_t g_mutex_cat = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
int OsShellCmdCat(int argc, const char **argv)
|
||||
{
|
||||
char *fullpath = NULL;
|
||||
int ret;
|
||||
CHAR buf[CAT_BUF_SIZE];
|
||||
size_t size;
|
||||
|
||||
char *shellWorkingDirectory = OsShellGetWorkingDirtectory();
|
||||
|
||||
if (shellWorkingDirectory == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ERROR_OUT_IF(argc != 1, PRINTK("cat [FILE]\n"), return -1);
|
||||
|
||||
ret = VfsNormalizePath(shellWorkingDirectory, argv[0], &fullpath);
|
||||
ERROR_OUT_IF(ret < 0, SetErr(-ret, "cat error"), return -1);
|
||||
|
||||
int fd = open(fullpath, O_RDONLY, 0666);
|
||||
|
||||
if (fd == -1) {
|
||||
ret = -1;
|
||||
free(fullpath);
|
||||
return ret;
|
||||
}
|
||||
|
||||
do {
|
||||
(void)memset_s(buf, sizeof(buf), 0, CAT_BUF_SIZE);
|
||||
size = read(fd, buf, CAT_BUF_SIZE - 1);
|
||||
if ((int)size < 0) {
|
||||
free(fullpath);
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
PRINTK("%s", buf);
|
||||
(void)LOS_TaskDelay(1);
|
||||
} while (size == CAT_BUF_SIZE);
|
||||
|
||||
free(fullpath);
|
||||
close(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int OsShellCmdMkdir(int argc, const char **argv)
|
||||
{
|
||||
int ret;
|
||||
char *fullpath = NULL;
|
||||
const char *filename = NULL;
|
||||
char *shellWorkingDirectory = OsShellGetWorkingDirtectory();
|
||||
if (shellWorkingDirectory == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ERROR_OUT_IF(argc != 1, PRINTK("mkdir [DIRECTORY]\n"), return 0);
|
||||
|
||||
filename = argv[0];
|
||||
ret = VfsNormalizePath(shellWorkingDirectory, filename, &fullpath);
|
||||
ERROR_OUT_IF(ret < 0, SetErr(-ret, "mkdir error"), return -1);
|
||||
|
||||
ret = mkdir(fullpath, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
if (ret == -1) {
|
||||
perror("mkdir error");
|
||||
}
|
||||
free(fullpath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OsShellCmdPwd(int argc, const char **argv)
|
||||
{
|
||||
char buf[SHOW_MAX_LEN] = {0};
|
||||
DIR *dir = NULL;
|
||||
char *shellWorkingDirectory = OsShellGetWorkingDirtectory();
|
||||
if (shellWorkingDirectory == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ERROR_OUT_IF(argc > 0, PRINTK("\nUsage: pwd\n"), return -1);
|
||||
|
||||
LOS_TaskLock();
|
||||
if (strncpy_s(buf, SHOW_MAX_LEN, shellWorkingDirectory, SHOW_MAX_LEN - 1) != EOK) {
|
||||
LOS_TaskUnlock();
|
||||
PRINTK("pwd error: strncpy_s error!\n");
|
||||
return -1;
|
||||
}
|
||||
LOS_TaskUnlock();
|
||||
|
||||
PRINTK("%s\n", buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OsShellCmdTouch(int argc, const char **argv)
|
||||
{
|
||||
int ret;
|
||||
int fd = -1;
|
||||
char *fullpath = NULL;
|
||||
const char *filename = NULL;
|
||||
char *shellWorkingDirectory = OsShellGetWorkingDirtectory();
|
||||
if (shellWorkingDirectory == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ERROR_OUT_IF(argc != 1, PRINTK("touch [FILE]\n"), return -1);
|
||||
|
||||
filename = argv[0];
|
||||
ret = VfsNormalizePath(shellWorkingDirectory, filename, &fullpath);
|
||||
ERROR_OUT_IF(ret < 0, SetErr(-ret, "touch error"), return -1);
|
||||
|
||||
fd = open(fullpath, O_RDWR | O_CREAT, 0777);
|
||||
free(fullpath);
|
||||
if (fd == -1) {
|
||||
perror("touch error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
(void)close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CP_BUF_SIZE 4096
|
||||
pthread_mutex_t g_mutexCp = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static int OsShellCmdDoCp(const char *srcFilePath, const char *dstFileName)
|
||||
{
|
||||
int ret;
|
||||
char *srcFullPath = NULL;
|
||||
char *drcFullPath = NULL;
|
||||
const char *srcFileName = NULL;
|
||||
char *dstFilePath = NULL;
|
||||
char *buf = NULL;
|
||||
const char *filename = NULL;
|
||||
size_t rdSize, wrSize;
|
||||
int srcFd = -1;
|
||||
int dstFd = -1;
|
||||
struct stat statBuf;
|
||||
mode_t srcMode;
|
||||
char *shellWorkingDirectory = OsShellGetWorkingDirtectory();
|
||||
if (shellWorkingDirectory == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf = (char *)malloc(CP_BUF_SIZE);
|
||||
if (buf == NULL) {
|
||||
PRINTK("cp error: Out of memory!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get source fullpath. */
|
||||
ret = VfsNormalizePath(shellWorkingDirectory, srcFilePath, &srcFullPath);
|
||||
if (ret < 0) {
|
||||
SetErrno(-ret);
|
||||
PRINTK("cp error: %s\n", strerror(errno));
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Is source path exist? */
|
||||
ret = stat(srcFullPath, &statBuf);
|
||||
if (ret == -1) {
|
||||
PRINTK("cp %s error: %s\n", srcFullPath, strerror(errno));
|
||||
goto errout_with_srcpath;
|
||||
}
|
||||
srcMode = statBuf.st_mode;
|
||||
/* Is source path a directory? */
|
||||
if (S_ISDIR(statBuf.st_mode)) {
|
||||
PRINTK("cp %s error: Source file can't be a directory.\n", srcFullPath);
|
||||
goto errout_with_srcpath;
|
||||
}
|
||||
|
||||
/* Get dest fullpath. */
|
||||
drcFullPath = strdup(dstFileName);
|
||||
if (drcFullPath == NULL) {
|
||||
PRINTK("cp error: Out of memory.\n");
|
||||
goto errout_with_srcpath;
|
||||
}
|
||||
/* Is dest path exist? */
|
||||
ret = stat(drcFullPath, &statBuf);
|
||||
if (ret == 0) {
|
||||
/* Is dest path a directory? */
|
||||
if (S_ISDIR(statBuf.st_mode)) {
|
||||
/* Get source file name without '/'. */
|
||||
srcFileName = srcFilePath;
|
||||
while (1) {
|
||||
filename = strchr(srcFileName, '/');
|
||||
if (filename == NULL) {
|
||||
break;
|
||||
}
|
||||
srcFileName = filename + 1;
|
||||
}
|
||||
/* Add the source file after dest path. */
|
||||
ret = VfsNormalizePath(drcFullPath, srcFileName, &dstFilePath);
|
||||
if (ret < 0) {
|
||||
SetErrno(-ret);
|
||||
PRINTK("cp error. %s.\n", strerror(errno));
|
||||
goto errout_with_path;
|
||||
}
|
||||
free(drcFullPath);
|
||||
drcFullPath = dstFilePath;
|
||||
}
|
||||
}
|
||||
|
||||
/* Is dest file same as source file? */
|
||||
if (strcmp(srcFullPath, drcFullPath) == 0) {
|
||||
PRINTK("cp error: '%s' and '%s' are the same file\n", srcFullPath, drcFullPath);
|
||||
goto errout_with_path;
|
||||
}
|
||||
|
||||
/* Copy begins. */
|
||||
(void)pthread_mutex_lock(&g_mutexCp);
|
||||
srcFd = open(srcFullPath, O_RDONLY);
|
||||
if (srcFd < 0) {
|
||||
PRINTK("cp error: can't open %s. %s.\n", srcFullPath, strerror(errno));
|
||||
goto errout_with_mutex;
|
||||
}
|
||||
|
||||
dstFd = open(drcFullPath, O_CREAT | O_WRONLY | O_TRUNC, srcMode);
|
||||
if (dstFd < 0) {
|
||||
PRINTK("cp error: can't create %s. %s.\n", drcFullPath, strerror(errno));
|
||||
goto errout_with_srcfd;
|
||||
}
|
||||
|
||||
do {
|
||||
(void)memset_s(buf, CP_BUF_SIZE, 0, CP_BUF_SIZE);
|
||||
rdSize = read(srcFd, buf, CP_BUF_SIZE);
|
||||
if (rdSize < 0) {
|
||||
PRINTK("cp %s %s failed. %s.\n", srcFullPath, drcFullPath, strerror(errno));
|
||||
goto errout_with_fd;
|
||||
}
|
||||
wrSize = write(dstFd, buf, rdSize);
|
||||
if (wrSize != rdSize) {
|
||||
PRINTK("cp %s %s failed. %s.\n", srcFullPath, drcFullPath, strerror(errno));
|
||||
goto errout_with_fd;
|
||||
}
|
||||
} while (rdSize == CP_BUF_SIZE);
|
||||
|
||||
/* Release resource. */
|
||||
free(buf);
|
||||
free(srcFullPath);
|
||||
free(drcFullPath);
|
||||
(void)close(srcFd);
|
||||
(void)close(dstFd);
|
||||
(void)pthread_mutex_unlock(&g_mutexCp);
|
||||
return LOS_OK;
|
||||
|
||||
errout_with_fd:
|
||||
(void)close(dstFd);
|
||||
errout_with_srcfd:
|
||||
(void)close(srcFd);
|
||||
errout_with_mutex:
|
||||
(void)pthread_mutex_unlock(&g_mutexCp);
|
||||
errout_with_path:
|
||||
free(drcFullPath);
|
||||
errout_with_srcpath:
|
||||
free(srcFullPath);
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* The separator and EOF for a directory fullpath: '/'and '\0' */
|
||||
#define SEPARATOR_EOF_LEN 2
|
||||
|
||||
static int OsShellCmdDoRmdir(const char *pathname)
|
||||
{
|
||||
struct dirent *dirent = NULL;
|
||||
struct stat statInfo;
|
||||
DIR *d = NULL;
|
||||
char *fullpath = NULL;
|
||||
int ret;
|
||||
|
||||
ret = memset_s(&statInfo, sizeof(struct stat), 0, sizeof(struct stat));
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
if (stat(pathname, &statInfo) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (S_ISREG(statInfo.st_mode) || S_ISLNK(statInfo.st_mode)) {
|
||||
return remove(pathname);
|
||||
}
|
||||
d = opendir(pathname);
|
||||
if (d == NULL) {
|
||||
return -1;
|
||||
}
|
||||
while (1) {
|
||||
dirent = readdir(d);
|
||||
if (dirent == NULL) {
|
||||
break;
|
||||
}
|
||||
if (strcmp(dirent->d_name, "..") && strcmp(dirent->d_name, ".")) {
|
||||
size_t fullPathBufSize = strlen(pathname) + strlen(dirent->d_name) + SEPARATOR_EOF_LEN;
|
||||
if (fullPathBufSize <= 0) {
|
||||
PRINTK("buffer size is invalid!\n");
|
||||
(void)closedir(d);
|
||||
return -1;
|
||||
}
|
||||
fullpath = (char *)malloc(fullPathBufSize);
|
||||
if (fullpath == NULL) {
|
||||
PRINTK("malloc failure!\n");
|
||||
(void)closedir(d);
|
||||
return -1;
|
||||
}
|
||||
ret = snprintf_s(fullpath, fullPathBufSize, fullPathBufSize - 1, "%s/%s", pathname, dirent->d_name);
|
||||
if (ret < 0) {
|
||||
PRINTK("name is too long!\n");
|
||||
free(fullpath);
|
||||
(void)closedir(d);
|
||||
return -1;
|
||||
}
|
||||
(void)OsShellCmdDoRmdir(fullpath);
|
||||
free(fullpath);
|
||||
}
|
||||
}
|
||||
(void)closedir(d);
|
||||
return rmdir(pathname);
|
||||
}
|
||||
|
||||
/* Wildcard matching operations */
|
||||
static int OsWildcardMatch(const char *src, const char *filename)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (*src != '\0') {
|
||||
if (*filename == '*') {
|
||||
while ((*filename == '*') || (*filename == '?')) {
|
||||
filename++;
|
||||
}
|
||||
|
||||
if (*filename == '\0') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (*src != '\0' && !(*src == *filename)) {
|
||||
src++;
|
||||
}
|
||||
|
||||
if (*src == '\0') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = OsWildcardMatch(src, filename);
|
||||
|
||||
while ((ret != 0) && (*(++src) != '\0')) {
|
||||
if (*src == *filename) {
|
||||
ret = OsWildcardMatch(src, filename);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
if ((*src == *filename) || (*filename == '?')) {
|
||||
return OsWildcardMatch(++src, ++filename);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
while (*filename != '\0') {
|
||||
if (*filename != '*') {
|
||||
return -1;
|
||||
}
|
||||
filename++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* To determine whether a wildcard character exists in a path */
|
||||
static int OsIsContainersWildcard(const char *filename)
|
||||
{
|
||||
while (*filename != '\0') {
|
||||
if ((*filename == '*') || (*filename == '?')) {
|
||||
return 1;
|
||||
}
|
||||
filename++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Delete a matching file or directory */
|
||||
|
||||
static int OsWildcardDeleteFileOrDir(const char *fullpath, wildcard_type mark)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (mark) {
|
||||
case RM_RECURSIVER:
|
||||
ret = OsShellCmdDoRmdir(fullpath);
|
||||
break;
|
||||
case RM_FILE:
|
||||
ret = unlink(fullpath);
|
||||
break;
|
||||
case RM_DIR:
|
||||
ret = rmdir(fullpath);
|
||||
break;
|
||||
default:
|
||||
return VFS_ERROR;
|
||||
}
|
||||
if (ret == -1) {
|
||||
PRINTK("%s ", fullpath);
|
||||
perror("rm/rmdir error!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
PRINTK("%s match successful!delete!\n", fullpath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Split the path with wildcard characters */
|
||||
|
||||
static char* OsWildcardSplitPath(char *fullpath, char **handle, char **wait)
|
||||
{
|
||||
int n;
|
||||
int a = 0;
|
||||
int b = 0;
|
||||
int len = strlen(fullpath);
|
||||
|
||||
for (n = 0; n < len; n++) {
|
||||
if (fullpath[n] == '/') {
|
||||
if (b != 0) {
|
||||
fullpath[n] = '\0';
|
||||
*wait = fullpath + n + 1;
|
||||
break;
|
||||
}
|
||||
a = n;
|
||||
} else if (fullpath[n] == '*' || fullpath[n] == '?') {
|
||||
b = n;
|
||||
fullpath[a] = '\0';
|
||||
if (a == 0) {
|
||||
*handle = fullpath + a + 1;
|
||||
continue;
|
||||
}
|
||||
*handle = fullpath + a + 1;
|
||||
}
|
||||
}
|
||||
return fullpath;
|
||||
}
|
||||
|
||||
/* Handling entry of the path with wildcard characters */
|
||||
|
||||
static int OsWildcardExtractDirectory(char *fullpath, void *dst, wildcard_type mark)
|
||||
{
|
||||
char separator[] = "/";
|
||||
char src[PATH_MAX] = {0};
|
||||
struct dirent *dirent = NULL;
|
||||
char *f = NULL;
|
||||
char *s = NULL;
|
||||
char *t = NULL;
|
||||
int ret = 0;
|
||||
DIR *d = NULL;
|
||||
struct stat statBuf;
|
||||
int deleteFlag = 0;
|
||||
|
||||
f = OsWildcardSplitPath(fullpath, &s, &t);
|
||||
|
||||
if (s == NULL) {
|
||||
if (mark == CP_FILE) {
|
||||
ret = OsShellCmdDoCp(fullpath, dst);
|
||||
} else if (mark == CP_COUNT) {
|
||||
ret = stat(fullpath, &statBuf);
|
||||
if (ret == 0 && (S_ISREG(statBuf.st_mode) || S_ISLNK(statBuf.st_mode))) {
|
||||
(*(int *)dst)++;
|
||||
}
|
||||
} else {
|
||||
ret = OsWildcardDeleteFileOrDir(fullpath, mark);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
d = (*f == '\0') ? opendir("/") : opendir(f);
|
||||
|
||||
if (d == NULL) {
|
||||
perror("opendir error");
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
dirent = readdir(d);
|
||||
if (dirent == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
ret = strcpy_s(src, PATH_MAX, f);
|
||||
if (ret != EOK) {
|
||||
goto closedir_out;
|
||||
}
|
||||
|
||||
ret = OsWildcardMatch(dirent->d_name, s);
|
||||
if (ret == 0) {
|
||||
ret = strcat_s(src, sizeof(src), separator);
|
||||
if (ret != EOK) {
|
||||
goto closedir_out;
|
||||
}
|
||||
ret = strcat_s(src, sizeof(src), dirent->d_name);
|
||||
if (ret != EOK) {
|
||||
goto closedir_out;
|
||||
}
|
||||
if (t == NULL) {
|
||||
if (mark == CP_FILE) {
|
||||
ret = OsShellCmdDoCp(src, dst);
|
||||
} else if (mark == CP_COUNT) {
|
||||
ret = stat(src, &statBuf);
|
||||
if (ret == 0 && (S_ISREG(statBuf.st_mode) || S_ISLNK(statBuf.st_mode))) {
|
||||
(*(int *)dst)++;
|
||||
if ((*(int *)dst) > 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = OsWildcardDeleteFileOrDir(src, mark);
|
||||
if (ret == 0) {
|
||||
deleteFlag = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = strcat_s(src, sizeof(src), separator);
|
||||
if (ret != EOK) {
|
||||
goto closedir_out;
|
||||
}
|
||||
ret = strcat_s(src, sizeof(src), t);
|
||||
if (ret != EOK) {
|
||||
goto closedir_out;
|
||||
}
|
||||
ret = OsWildcardExtractDirectory(src, dst, mark);
|
||||
if (mark == CP_COUNT && (*(int *)dst) > 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
(void)closedir(d);
|
||||
if (deleteFlag == 1) {
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
closedir_out:
|
||||
(void)closedir(d);
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
int OsShellCmdCp(int argc, const char **argv)
|
||||
{
|
||||
int ret;
|
||||
const char *src = NULL;
|
||||
const char *dst = NULL;
|
||||
char *srcFullPath = NULL;
|
||||
char *drcFullPath = NULL;
|
||||
struct stat statBuf;
|
||||
int count = 0;
|
||||
char *shellWorkingDirectory = OsShellGetWorkingDirtectory();
|
||||
if (shellWorkingDirectory == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ERROR_OUT_IF(argc < 2, PRINTK("cp [SOURCEFILE] [DESTFILE]\n"), return -1);
|
||||
|
||||
src = argv[0];
|
||||
dst = argv[1];
|
||||
|
||||
/* Get source fullpath. */
|
||||
|
||||
ret = VfsNormalizePath(shellWorkingDirectory, src, &srcFullPath);
|
||||
if (ret < 0) {
|
||||
SetErrno(-ret);
|
||||
PRINTK("cp error:%s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (src[strlen(src) - 1] == '/') {
|
||||
PRINTK("cp %s error: Source file can't be a directory.\n", src);
|
||||
goto errout_with_srcpath;
|
||||
}
|
||||
|
||||
/* Get dest fullpath. */
|
||||
ret = VfsNormalizePath(shellWorkingDirectory, dst, &drcFullPath);
|
||||
if (ret < 0) {
|
||||
SetErrno(-ret);
|
||||
PRINTK("cp error: can't open %s. %s\n", dst, strerror(errno));
|
||||
goto errout_with_srcpath;
|
||||
}
|
||||
|
||||
/* Is dest path exist? */
|
||||
|
||||
ret = stat(drcFullPath, &statBuf);
|
||||
if (ret < 0) {
|
||||
/* Is dest path a directory? */
|
||||
if (dst[strlen(dst) - 1] == '/') {
|
||||
PRINTK("cp error: %s, %s.\n", drcFullPath, strerror(errno));
|
||||
goto errout_with_path;
|
||||
}
|
||||
} else {
|
||||
if ((S_ISREG(statBuf.st_mode) || S_ISLNK(statBuf.st_mode)) && dst[strlen(dst) - 1] == '/') {
|
||||
PRINTK("cp error: %s is not a directory.\n", drcFullPath);
|
||||
goto errout_with_path;
|
||||
}
|
||||
}
|
||||
|
||||
if (OsIsContainersWildcard(srcFullPath)) {
|
||||
if (ret < 0 || S_ISREG(statBuf.st_mode) || S_ISLNK(statBuf.st_mode)) {
|
||||
char *srcCopy = strdup(srcFullPath);
|
||||
if (srcCopy == NULL) {
|
||||
PRINTK("cp error : Out of memory.\n");
|
||||
goto errout_with_path;
|
||||
}
|
||||
(void)OsWildcardExtractDirectory(srcCopy, &count, CP_COUNT);
|
||||
free(srcCopy);
|
||||
if (count > 1) {
|
||||
PRINTK("cp error : %s is not a directory.\n", drcFullPath);
|
||||
goto errout_with_path;
|
||||
}
|
||||
}
|
||||
ret = OsWildcardExtractDirectory(srcFullPath, drcFullPath, CP_FILE);
|
||||
} else {
|
||||
ret = OsShellCmdDoCp(srcFullPath, drcFullPath);
|
||||
}
|
||||
free(drcFullPath);
|
||||
free(srcFullPath);
|
||||
return ret;
|
||||
|
||||
errout_with_path:
|
||||
free(drcFullPath);
|
||||
errout_with_srcpath:
|
||||
free(srcFullPath);
|
||||
return VFS_ERROR;
|
||||
}
|
||||
|
||||
static inline void PrintRmUsage(void)
|
||||
{
|
||||
PRINTK("rm [FILE] or rm [-r/-R] [FILE]\n");
|
||||
}
|
||||
|
||||
int OsShellCmdRm(int argc, const char **argv)
|
||||
{
|
||||
int ret;
|
||||
char *fullpath = NULL;
|
||||
const char *filename = NULL;
|
||||
char *shellWorkingDirectory = OsShellGetWorkingDirtectory();
|
||||
|
||||
if (shellWorkingDirectory == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ERROR_OUT_IF(argc != 1 && argc != 2, PrintRmUsage(), return -1);
|
||||
|
||||
if (argc == 2) {
|
||||
ERROR_OUT_IF(strcmp(argv[0], "-r") != 0 && strcmp(argv[0], "-R") != 0, PrintRmUsage(), return -1);
|
||||
|
||||
filename = argv[1];
|
||||
ret = VfsNormalizePath(shellWorkingDirectory, filename, &fullpath);
|
||||
ERROR_OUT_IF(ret < 0, SetErr(-ret, "rm error"), return -1);
|
||||
|
||||
if (OsIsContainersWildcard(fullpath)) {
|
||||
ret = OsWildcardExtractDirectory(fullpath, NULL, RM_RECURSIVER);
|
||||
} else {
|
||||
ret = OsShellCmdDoRmdir(fullpath);
|
||||
}
|
||||
} else {
|
||||
filename = argv[0];
|
||||
ret = VfsNormalizePath(shellWorkingDirectory, filename, &fullpath);
|
||||
ERROR_OUT_IF(ret < 0, SetErr(-ret, "rm error"), return -1);
|
||||
|
||||
if (OsIsContainersWildcard(fullpath)) {
|
||||
ret = OsWildcardExtractDirectory(fullpath, NULL, RM_FILE);
|
||||
} else {
|
||||
ret = unlink(fullpath);
|
||||
}
|
||||
}
|
||||
if (ret == -1) {
|
||||
perror("rm error");
|
||||
}
|
||||
free(fullpath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OsShellCmdRmdir(int argc, const char **argv)
|
||||
{
|
||||
int ret;
|
||||
char *fullpath = NULL;
|
||||
const char *filename = NULL;
|
||||
char *shellWorkingDirectory = OsShellGetWorkingDirtectory();
|
||||
if (shellWorkingDirectory == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ERROR_OUT_IF(argc == 0, PRINTK("rmdir [DIRECTORY]\n"), return -1);
|
||||
|
||||
filename = argv[0];
|
||||
ret = VfsNormalizePath(shellWorkingDirectory, filename, &fullpath);
|
||||
ERROR_OUT_IF(ret < 0, SetErr(-ret, "rmdir error"), return -1);
|
||||
|
||||
if (OsIsContainersWildcard(fullpath)) {
|
||||
ret = OsWildcardExtractDirectory(fullpath, NULL, RM_DIR);
|
||||
} else {
|
||||
ret = rmdir(fullpath);
|
||||
}
|
||||
if (ret == -1) {
|
||||
PRINTK("rmdir %s failed. Error: %s.\n", fullpath, strerror(errno));
|
||||
}
|
||||
free(fullpath);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
50
components/trace/BUILD.gn
Normal file
50
components/trace/BUILD.gn
Normal file
@@ -0,0 +1,50 @@
|
||||
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
# of conditions and the following disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
# to endorse or promote products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import("//kernel/liteos_m/config.gni")
|
||||
|
||||
static_library("trace") {
|
||||
sources = [
|
||||
"cnv/trace_cnv.c",
|
||||
"los_trace.c",
|
||||
"pipeline/serial/trace_pipeline_serial.c",
|
||||
"pipeline/trace_pipeline.c",
|
||||
"pipeline/trace_tlv.c",
|
||||
"trace_offline.c",
|
||||
"trace_online.c",
|
||||
]
|
||||
|
||||
include_dirs = [
|
||||
"./",
|
||||
"cnv",
|
||||
"pipeline",
|
||||
"pipeline/serial",
|
||||
]
|
||||
configs += [ "$LITEOSTOPDIR:los_config" ]
|
||||
}
|
||||
272
components/trace/cnv/trace_cnv.c
Normal file
272
components/trace/cnv/trace_cnv.c
Normal file
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "trace_cnv.h"
|
||||
#include "los_trace.h"
|
||||
#include "los_task.h"
|
||||
#include "los_sem.h"
|
||||
#include "los_mux.h"
|
||||
#include "los_queue.h"
|
||||
#include "los_event.h"
|
||||
#include "los_swtmr.h"
|
||||
#include "los_hook.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
STATIC VOID LOS_TraceMemInit(VOID *pool, UINT32 size)
|
||||
{
|
||||
LOS_TRACE(MEM_INFO_REQ, pool);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceMemAlloc(VOID *pool, VOID *ptr, UINT32 size)
|
||||
{
|
||||
LOS_TRACE(MEM_ALLOC, pool, (UINTPTR)ptr, size);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceMemFree(VOID *pool, VOID *ptr)
|
||||
{
|
||||
LOS_TRACE(MEM_FREE, pool, (UINTPTR)ptr);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceMemRealloc(VOID *pool, VOID *ptr, UINT32 size)
|
||||
{
|
||||
LOS_TRACE(MEM_REALLOC, pool, (UINTPTR)ptr, size);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceMemAllocAlign(VOID *pool, VOID *ptr, UINT32 size, UINT32 boundary)
|
||||
{
|
||||
LOS_TRACE(MEM_ALLOC_ALIGN, pool, (UINTPTR)ptr, size, boundary);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceEventInit(PEVENT_CB_S eventCB)
|
||||
{
|
||||
LOS_TRACE(EVENT_CREATE, (UINTPTR)eventCB);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceEventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout)
|
||||
{
|
||||
LOS_TRACE(EVENT_READ, (UINTPTR)eventCB, eventCB->uwEventID, eventMask, mode, timeout);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceEventWrite(PEVENT_CB_S eventCB, UINT32 events)
|
||||
{
|
||||
LOS_TRACE(EVENT_WRITE, (UINTPTR)eventCB, eventCB->uwEventID, events);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceEventClear(PEVENT_CB_S eventCB, UINT32 events)
|
||||
{
|
||||
LOS_TRACE(EVENT_CLEAR, (UINTPTR)eventCB, eventCB->uwEventID, events);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceEventDestroy(PEVENT_CB_S eventCB)
|
||||
{
|
||||
LOS_TRACE(EVENT_DELETE, (UINTPTR)eventCB, LOS_OK);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceQueueCreate(const LosQueueCB *queueCB)
|
||||
{
|
||||
LOS_TRACE(QUEUE_CREATE, queueCB->queueID, queueCB->queueLen, queueCB->queueSize - sizeof(UINT32),
|
||||
(UINTPTR)queueCB, 0);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceQueueRW(const LosQueueCB *queueCB, UINT32 operateType,
|
||||
UINT32 bufferSize, UINT32 timeout)
|
||||
{
|
||||
LOS_TRACE(QUEUE_RW, queueCB->queueID, queueCB->queueSize, bufferSize, operateType,
|
||||
queueCB->readWriteableCnt[OS_QUEUE_READ], queueCB->readWriteableCnt[OS_QUEUE_WRITE], timeout);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceQueueDelete(const LosQueueCB *queueCB)
|
||||
{
|
||||
LOS_TRACE(QUEUE_DELETE, queueCB->queueID, queueCB->queueState, queueCB->readWriteableCnt[OS_QUEUE_READ]);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceSemCreate(const LosSemCB *semCB)
|
||||
{
|
||||
LOS_TRACE(SEM_CREATE, semCB->semID, 0, semCB->semCount);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceSemPost(const LosSemCB *semCB, const LosTaskCB *resumedTask)
|
||||
{
|
||||
(VOID)resumedTask;
|
||||
LOS_TRACE(SEM_POST, semCB->semID, 0, semCB->semCount);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceSemPend(const LosSemCB *semCB, const LosTaskCB *runningTask, UINT32 timeout)
|
||||
{
|
||||
(VOID)runningTask;
|
||||
LOS_TRACE(SEM_PEND, semCB->semID, semCB->semCount, timeout);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceSemDelete(const LosSemCB *semCB)
|
||||
{
|
||||
LOS_TRACE(SEM_DELETE, semCB->semID, LOS_OK);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceMuxCreate(const LosMuxCB *muxCB)
|
||||
{
|
||||
LOS_TRACE(MUX_CREATE, muxCB->muxID);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceMuxPost(const LosMuxCB *muxCB)
|
||||
{
|
||||
LOS_TRACE(MUX_POST, muxCB->muxID, muxCB->muxCount,
|
||||
(muxCB->owner == NULL) ? 0xffffffff : muxCB->owner->taskID);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceMuxPend(const LosMuxCB *muxCB, UINT32 timeout)
|
||||
{
|
||||
LOS_TRACE(MUX_PEND, muxCB->muxID, muxCB->muxCount,
|
||||
(muxCB->owner == NULL) ? 0xffffffff : muxCB->owner->taskID, timeout);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceMuxDelete(const LosMuxCB *muxCB)
|
||||
{
|
||||
LOS_TRACE(MUX_DELETE, muxCB->muxID, muxCB->muxStat, muxCB->muxCount,
|
||||
(muxCB->owner == NULL) ? 0xffffffff : muxCB->owner->taskID);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceTaskCreate(const LosTaskCB *taskCB)
|
||||
{
|
||||
LOS_TRACE(TASK_CREATE, taskCB->taskID, taskCB->taskStatus, taskCB->priority);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceTaskPriModify(const LosTaskCB *taskCB, UINT32 prio)
|
||||
{
|
||||
LOS_TRACE(TASK_PRIOSET, taskCB->taskID, taskCB->taskStatus, taskCB->priority, prio);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceTaskDelete(const LosTaskCB *taskCB)
|
||||
{
|
||||
LOS_TRACE(TASK_DELETE, taskCB->taskID, taskCB->taskStatus, (UINTPTR)taskCB->stackPointer);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceTaskSwitchedIn(VOID)
|
||||
{
|
||||
LosTaskCB *newTask = g_losTask.newTask;
|
||||
LosTaskCB *runTask = g_losTask.runTask;
|
||||
LOS_TRACE(TASK_SWITCH, newTask->taskID, runTask->priority, runTask->taskStatus,
|
||||
newTask->priority, newTask->taskStatus);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceTaskResume(const LosTaskCB *taskCB)
|
||||
{
|
||||
LOS_TRACE(TASK_RESUME, taskCB->taskID, taskCB->taskStatus, taskCB->priority);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceTaskSuspend(const LosTaskCB *taskCB)
|
||||
{
|
||||
LOS_TRACE(TASK_SUSPEND, taskCB->taskID, taskCB->taskStatus, g_losTask.runTask->taskID);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceIsrEnter(UINT32 hwiNum)
|
||||
{
|
||||
LOS_TRACE(HWI_RESPONSE_IN, hwiNum);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceIsrExit(UINT32 hwiNum)
|
||||
{
|
||||
LOS_TRACE(HWI_RESPONSE_OUT, hwiNum);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceSwtmrCreate(const SWTMR_CTRL_S *swtmr)
|
||||
{
|
||||
LOS_TRACE(SWTMR_CREATE, swtmr->usTimerID);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceSwtmrDelete(const SWTMR_CTRL_S *swtmr)
|
||||
{
|
||||
LOS_TRACE(SWTMR_DELETE, swtmr->usTimerID);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceSwtmrExpired(const SWTMR_CTRL_S *swtmr)
|
||||
{
|
||||
LOS_TRACE(SWTMR_EXPIRED, swtmr->usTimerID);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceSwtmrStart(const SWTMR_CTRL_S *swtmr)
|
||||
{
|
||||
LOS_TRACE(SWTMR_START, swtmr->usTimerID, swtmr->ucMode, swtmr->uwInterval);
|
||||
}
|
||||
|
||||
STATIC VOID LOS_TraceSwtmrStop(const SWTMR_CTRL_S *swtmr)
|
||||
{
|
||||
LOS_TRACE(SWTMR_STOP, swtmr->usTimerID);
|
||||
}
|
||||
|
||||
VOID OsTraceCnvInit(VOID)
|
||||
{
|
||||
LOS_HookReg(LOS_HOOK_TYPE_MEM_ALLOC, LOS_TraceMemAlloc);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_MEM_FREE, LOS_TraceMemFree);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_MEM_INIT, LOS_TraceMemInit);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_MEM_REALLOC, LOS_TraceMemRealloc);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_MEM_ALLOCALIGN, LOS_TraceMemAllocAlign);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_EVENT_INIT, LOS_TraceEventInit);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_EVENT_READ, LOS_TraceEventRead);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_EVENT_WRITE, LOS_TraceEventWrite);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_EVENT_CLEAR, LOS_TraceEventClear);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_EVENT_DESTROY, LOS_TraceEventDestroy);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_QUEUE_CREATE, LOS_TraceQueueCreate);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_QUEUE_DELETE, LOS_TraceQueueDelete);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_QUEUE_READ, LOS_TraceQueueRW);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_QUEUE_WRITE, LOS_TraceQueueRW);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_SEM_CREATE, LOS_TraceSemCreate);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_SEM_DELETE, LOS_TraceSemDelete);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_SEM_POST, LOS_TraceSemPost);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_SEM_PEND, LOS_TraceSemPend);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_MUX_CREATE, LOS_TraceMuxCreate);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_MUX_POST, LOS_TraceMuxPost);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_MUX_PEND, LOS_TraceMuxPend);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_MUX_DELETE, LOS_TraceMuxDelete);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_TASK_PRIMODIFY, LOS_TraceTaskPriModify);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_TASK_DELETE, LOS_TraceTaskDelete);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_TASK_CREATE, LOS_TraceTaskCreate);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_TASK_SWITCHEDIN, LOS_TraceTaskSwitchedIn);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_MOVEDTASKTOREADYSTATE, LOS_TraceTaskResume);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_MOVEDTASKTOSUSPENDEDLIST, LOS_TraceTaskSuspend);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_ISR_ENTER, LOS_TraceIsrEnter);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_ISR_EXIT, LOS_TraceIsrExit);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_SWTMR_CREATE, LOS_TraceSwtmrCreate);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_SWTMR_DELETE, LOS_TraceSwtmrDelete);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_SWTMR_EXPIRED, LOS_TraceSwtmrExpired);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_SWTMR_START, LOS_TraceSwtmrStart);
|
||||
LOS_HookReg(LOS_HOOK_TYPE_SWTMR_STOP, LOS_TraceSwtmrStop);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
@@ -1,42 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "stdio_impl.h"
|
||||
|
||||
int __wrap_fclose(FILE *f)
|
||||
{
|
||||
return __fclose(f);
|
||||
}
|
||||
|
||||
int __wrap_fflush(FILE *f)
|
||||
{
|
||||
return __fflush(f);
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _TRACE_CNV_H
|
||||
#define _TRACE_CNV_H
|
||||
|
||||
#include "stdarg.h"
|
||||
#include "los_compiler.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
extern VOID OsTraceCnvInit(VOID);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _TRACE_CNV_H */
|
||||
434
components/trace/los_trace.c
Normal file
434
components/trace/los_trace.c
Normal file
@@ -0,0 +1,434 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_trace_pri.h"
|
||||
#include "trace_pipeline.h"
|
||||
#include "los_memory.h"
|
||||
#include "los_config.h"
|
||||
#include "securec.h"
|
||||
#include "trace_cnv.h"
|
||||
|
||||
#if (LOSCFG_KERNEL_SMP == 1)
|
||||
#include "los_mp_pri.h"
|
||||
#endif
|
||||
|
||||
#if (LOSCFG_SHELL == 1)
|
||||
#include "shcmd.h"
|
||||
#include "shell.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if (LOSCFG_KERNEL_TRACE == 1)
|
||||
LITE_OS_SEC_BSS STATIC UINT32 g_traceEventCount;
|
||||
LITE_OS_SEC_BSS STATIC volatile enum TraceState g_traceState = TRACE_UNINIT;
|
||||
LITE_OS_SEC_DATA_INIT STATIC volatile BOOL g_enableTrace = FALSE;
|
||||
LITE_OS_SEC_BSS STATIC UINT32 g_traceMask = TRACE_DEFAULT_MASK;
|
||||
|
||||
TRACE_EVENT_HOOK g_traceEventHook = NULL;
|
||||
TRACE_DUMP_HOOK g_traceDumpHook = NULL;
|
||||
|
||||
#if (LOSCFG_TRACE_CONTROL_AGENT == 1)
|
||||
LITE_OS_SEC_BSS STATIC UINT32 g_traceTaskId;
|
||||
#endif
|
||||
|
||||
#define EVENT_MASK 0xFFFFFFF0
|
||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
|
||||
LITE_OS_SEC_BSS STATIC TRACE_HWI_FILTER_HOOK g_traceHwiFliterHook = NULL;
|
||||
|
||||
#if (LOSCFG_KERNEL_SMP == 1)
|
||||
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_traceSpin);
|
||||
#endif
|
||||
|
||||
STATIC_INLINE BOOL OsTraceHwiFilter(UINT32 hwiNum)
|
||||
{
|
||||
BOOL ret = ((hwiNum == NUM_HAL_INTERRUPT_UART) || (hwiNum == OS_TICK_INT_NUM));
|
||||
#if (LOSCFG_KERNEL_SMP == 1)
|
||||
ret |= (hwiNum == LOS_MP_IPI_SCHEDULE);
|
||||
#endif
|
||||
if (g_traceHwiFliterHook != NULL) {
|
||||
ret |= g_traceHwiFliterHook(hwiNum);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATIC VOID OsTraceSetFrame(TraceEventFrame *frame, UINT32 eventType, UINTPTR identity, const UINTPTR *params,
|
||||
UINT16 paramCount)
|
||||
{
|
||||
INT32 i;
|
||||
UINT32 intSave;
|
||||
|
||||
(VOID)memset_s(frame, sizeof(TraceEventFrame), 0, sizeof(TraceEventFrame));
|
||||
|
||||
if (paramCount > LOSCFG_TRACE_FRAME_MAX_PARAMS) {
|
||||
paramCount = LOSCFG_TRACE_FRAME_MAX_PARAMS;
|
||||
}
|
||||
|
||||
TRACE_LOCK(intSave);
|
||||
frame->curTask = OsTraceGetMaskTid(LOS_CurTaskIDGet());
|
||||
frame->identity = identity;
|
||||
frame->curTime = LOS_SysCycleGet();
|
||||
frame->eventType = eventType;
|
||||
|
||||
#if (LOSCFG_TRACE_FRAME_CORE_MSG == 1)
|
||||
frame->core.cpuId = ArchCurrCpuid();
|
||||
frame->core.hwiActive = OS_INT_ACTIVE ? TRUE : FALSE;
|
||||
frame->core.taskLockCnt = MIN(OsPercpuGet()->taskLockCnt, 0xF); /* taskLockCnt is 4 bits, max vaule = 0xF */
|
||||
frame->core.paramCount = paramCount;
|
||||
#endif
|
||||
|
||||
#if (LOSCFG_TRACE_FRAME_EVENT_COUNT == 1)
|
||||
frame->eventCount = g_traceEventCount;
|
||||
g_traceEventCount++;
|
||||
#endif
|
||||
TRACE_UNLOCK(intSave);
|
||||
|
||||
for (i = 0; i < paramCount; i++) {
|
||||
frame->params[i] = params[i];
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsTraceSetObj(ObjData *obj, const LosTaskCB *tcb)
|
||||
{
|
||||
errno_t ret;
|
||||
(VOID)memset_s(obj, sizeof(ObjData), 0, sizeof(ObjData));
|
||||
|
||||
obj->id = OsTraceGetMaskTid(tcb->taskID);
|
||||
obj->prio = tcb->priority;
|
||||
|
||||
ret = strncpy_s(obj->name, LOSCFG_TRACE_OBJ_MAX_NAME_SIZE, tcb->taskName, LOSCFG_TRACE_OBJ_MAX_NAME_SIZE - 1);
|
||||
if (ret != EOK) {
|
||||
TRACE_ERROR("Task name copy failed!\n");
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsTraceHook(UINT32 eventType, UINTPTR identity, const UINTPTR *params, UINT16 paramCount)
|
||||
{
|
||||
if ((eventType == TASK_CREATE) || (eventType == TASK_PRIOSET)) {
|
||||
OsTraceObjAdd(eventType, identity); /* handle important obj info, these can not be filtered */
|
||||
}
|
||||
|
||||
if ((g_enableTrace == TRUE) && (eventType & g_traceMask)) {
|
||||
UINTPTR id = identity;
|
||||
if (TRACE_GET_MODE_FLAG(eventType) == TRACE_HWI_FLAG) {
|
||||
if (OsTraceHwiFilter(identity)) {
|
||||
return;
|
||||
}
|
||||
} else if (TRACE_GET_MODE_FLAG(eventType) == TRACE_TASK_FLAG) {
|
||||
id = OsTraceGetMaskTid(identity);
|
||||
} else if (eventType == MEM_INFO_REQ) {
|
||||
LOS_MEM_POOL_STATUS status;
|
||||
LOS_MemInfoGet((VOID *)identity, &status);
|
||||
LOS_TRACE(MEM_INFO, identity, status.totalUsedSize, status.totalFreeSize);
|
||||
return;
|
||||
}
|
||||
|
||||
TraceEventFrame frame;
|
||||
OsTraceSetFrame(&frame, eventType, id, params, paramCount);
|
||||
|
||||
OsTraceWriteOrSendEvent(&frame);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL OsTraceIsEnable(VOID)
|
||||
{
|
||||
return g_enableTrace == TRUE;
|
||||
}
|
||||
|
||||
STATIC VOID OsTraceHookInstall(VOID)
|
||||
{
|
||||
g_traceEventHook = OsTraceHook;
|
||||
#if (LOSCFG_RECORDER_MODE_OFFLINE == 1)
|
||||
g_traceDumpHook = OsTraceRecordDump;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (LOSCFG_TRACE_CONTROL_AGENT == 1)
|
||||
STATIC BOOL OsTraceCmdIsValid(const TraceClientCmd *msg)
|
||||
{
|
||||
return ((msg->end == TRACE_CMD_END_CHAR) && (msg->cmd < TRACE_CMD_MAX_CODE));
|
||||
}
|
||||
|
||||
STATIC VOID OsTraceCmdHandle(const TraceClientCmd *msg)
|
||||
{
|
||||
if (!OsTraceCmdIsValid(msg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (msg->cmd) {
|
||||
case TRACE_CMD_START:
|
||||
LOS_TraceStart();
|
||||
break;
|
||||
case TRACE_CMD_STOP:
|
||||
LOS_TraceStop();
|
||||
break;
|
||||
case TRACE_CMD_SET_EVENT_MASK:
|
||||
/* 4 params(UINT8) composition the mask(UINT32) */
|
||||
LOS_TraceEventMaskSet(TRACE_MASK_COMBINE(msg->param1, msg->param2, msg->param3, msg->param4));
|
||||
break;
|
||||
case TRACE_CMD_RECODE_DUMP:
|
||||
LOS_TraceRecordDump(TRUE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VOID TraceAgent(VOID)
|
||||
{
|
||||
UINT32 ret;
|
||||
TraceClientCmd msg;
|
||||
|
||||
while (1) {
|
||||
(VOID)memset_s(&msg, sizeof(TraceClientCmd), 0, sizeof(TraceClientCmd));
|
||||
ret = OsTraceDataWait();
|
||||
if (ret == LOS_OK) {
|
||||
OsTraceDataRecv((UINT8 *)&msg, sizeof(TraceClientCmd), 0);
|
||||
OsTraceCmdHandle(&msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC UINT32 OsCreateTraceAgentTask(VOID)
|
||||
{
|
||||
UINT32 ret;
|
||||
TSK_INIT_PARAM_S taskInitParam;
|
||||
|
||||
(VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
|
||||
taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)TraceAgent;
|
||||
taskInitParam.usTaskPrio = LOSCFG_TRACE_TASK_PRIORITY;
|
||||
taskInitParam.pcName = "TraceAgent";
|
||||
taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
|
||||
#if (LOSCFG_KERNEL_SMP == 1)
|
||||
taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid());
|
||||
#endif
|
||||
ret = LOS_TaskCreate(&g_traceTaskId, &taskInitParam);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
UINT32 OsTraceInit(VOID)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINT32 ret;
|
||||
|
||||
TRACE_LOCK(intSave);
|
||||
if (g_traceState != TRACE_UNINIT) {
|
||||
TRACE_ERROR("trace has been initialized already, the current state is :%d\n", g_traceState);
|
||||
ret = LOS_ERRNO_TRACE_ERROR_STATUS;
|
||||
goto LOS_ERREND;
|
||||
}
|
||||
|
||||
#if (LOSCFG_TRACE_CLIENT_INTERACT == 1)
|
||||
ret = OsTracePipelineInit();
|
||||
if (ret != LOS_OK) {
|
||||
goto LOS_ERREND;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (LOSCFG_TRACE_CONTROL_AGENT == 1)
|
||||
ret = OsCreateTraceAgentTask();
|
||||
if (ret != LOS_OK) {
|
||||
TRACE_ERROR("trace init create agentTask error :0x%x\n", ret);
|
||||
goto LOS_ERREND;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (LOSCFG_RECORDER_MODE_OFFLINE == 1)
|
||||
ret = OsTraceBufInit(LOSCFG_TRACE_BUFFER_SIZE);
|
||||
if (ret != LOS_OK) {
|
||||
#if (LOSCFG_TRACE_CONTROL_AGENT == 1)
|
||||
(VOID)LOS_TaskDelete(g_traceTaskId);
|
||||
#endif
|
||||
goto LOS_ERREND;
|
||||
}
|
||||
#endif
|
||||
|
||||
OsTraceHookInstall();
|
||||
OsTraceCnvInit();
|
||||
|
||||
g_traceEventCount = 0;
|
||||
|
||||
#if (LOSCFG_RECORDER_MODE_ONLINE == 1) /* Wait trace client to start trace */
|
||||
g_enableTrace = FALSE;
|
||||
g_traceState = TRACE_INITED;
|
||||
#else
|
||||
g_enableTrace = TRUE;
|
||||
g_traceState = TRACE_STARTED;
|
||||
#endif
|
||||
TRACE_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
LOS_ERREND:
|
||||
TRACE_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
|
||||
UINT32 LOS_TraceStart(VOID)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINT32 ret = LOS_OK;
|
||||
|
||||
TRACE_LOCK(intSave);
|
||||
if (g_traceState == TRACE_STARTED) {
|
||||
goto START_END;
|
||||
}
|
||||
|
||||
if (g_traceState == TRACE_UNINIT) {
|
||||
TRACE_ERROR("trace not inited, be sure LOS_TraceInit excute success\n");
|
||||
ret = LOS_ERRNO_TRACE_ERROR_STATUS;
|
||||
goto START_END;
|
||||
}
|
||||
|
||||
OsTraceNotifyStart();
|
||||
|
||||
g_enableTrace = TRUE;
|
||||
g_traceState = TRACE_STARTED;
|
||||
|
||||
TRACE_UNLOCK(intSave);
|
||||
LOS_TRACE(MEM_INFO_REQ, m_aucSysMem0);
|
||||
return ret;
|
||||
START_END:
|
||||
TRACE_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
|
||||
VOID LOS_TraceStop(VOID)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
TRACE_LOCK(intSave);
|
||||
if (g_traceState != TRACE_STARTED) {
|
||||
goto STOP_END;
|
||||
}
|
||||
|
||||
g_enableTrace = FALSE;
|
||||
g_traceState = TRACE_STOPED;
|
||||
OsTraceNotifyStop();
|
||||
STOP_END:
|
||||
TRACE_UNLOCK(intSave);
|
||||
}
|
||||
|
||||
VOID LOS_TraceEventMaskSet(UINT32 mask)
|
||||
{
|
||||
g_traceMask = mask & EVENT_MASK;
|
||||
}
|
||||
|
||||
VOID LOS_TraceRecordDump(BOOL toClient)
|
||||
{
|
||||
if (g_traceState != TRACE_STOPED) {
|
||||
TRACE_ERROR("trace dump must after trace stopped , the current state is : %d\n", g_traceState);
|
||||
return;
|
||||
}
|
||||
OsTraceRecordDump(toClient);
|
||||
}
|
||||
|
||||
OfflineHead *LOS_TraceRecordGet(VOID)
|
||||
{
|
||||
return OsTraceRecordGet();
|
||||
}
|
||||
|
||||
VOID LOS_TraceReset(VOID)
|
||||
{
|
||||
if (g_traceState == TRACE_UNINIT) {
|
||||
TRACE_ERROR("trace not inited, be sure LOS_TraceInit excute success\n");
|
||||
return;
|
||||
}
|
||||
|
||||
OsTraceReset();
|
||||
}
|
||||
|
||||
VOID LOS_TraceHwiFilterHookReg(TRACE_HWI_FILTER_HOOK hook)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
TRACE_LOCK(intSave);
|
||||
g_traceHwiFliterHook = hook;
|
||||
TRACE_UNLOCK(intSave);
|
||||
}
|
||||
|
||||
#if (LOSCFG_SHELL == 1)
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdTraceSetMask(INT32 argc, const CHAR **argv)
|
||||
{
|
||||
size_t mask;
|
||||
CHAR *endPtr = NULL;
|
||||
|
||||
if (argc >= 2) { /* 2:Just as number of parameters */
|
||||
PRINTK("\nUsage: trace_mask or trace_mask ID\n");
|
||||
return OS_ERROR;
|
||||
}
|
||||
|
||||
if (argc == 0) {
|
||||
mask = TRACE_DEFAULT_MASK;
|
||||
} else {
|
||||
mask = strtoul(argv[0], &endPtr, 0);
|
||||
}
|
||||
LOS_TraceEventMaskSet((UINT32)mask);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdTraceDump(INT32 argc, const CHAR **argv)
|
||||
{
|
||||
BOOL toClient;
|
||||
CHAR *endPtr = NULL;
|
||||
|
||||
if (argc >= 2) { /* 2:Just as number of parameters */
|
||||
PRINTK("\nUsage: trace_dump or trace_dump [1/0]\n");
|
||||
return OS_ERROR;
|
||||
}
|
||||
|
||||
if (argc == 0) {
|
||||
toClient = FALSE;
|
||||
} else {
|
||||
toClient = strtoul(argv[0], &endPtr, 0) != 0 ? TRUE : FALSE;
|
||||
}
|
||||
LOS_TraceRecordDump(toClient);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
SHELLCMD_ENTRY(tracestart_shellcmd, CMD_TYPE_EX, "trace_start", 0, (CmdCallBackFunc)LOS_TraceStart);
|
||||
SHELLCMD_ENTRY(tracestop_shellcmd, CMD_TYPE_EX, "trace_stop", 0, (CmdCallBackFunc)LOS_TraceStop);
|
||||
SHELLCMD_ENTRY(tracesetmask_shellcmd, CMD_TYPE_EX, "trace_mask", 1, (CmdCallBackFunc)OsShellCmdTraceSetMask);
|
||||
SHELLCMD_ENTRY(tracereset_shellcmd, CMD_TYPE_EX, "trace_reset", 0, (CmdCallBackFunc)LOS_TraceReset);
|
||||
SHELLCMD_ENTRY(tracedump_shellcmd, CMD_TYPE_EX, "trace_dump", 1, (CmdCallBackFunc)OsShellCmdTraceDump);
|
||||
#endif
|
||||
|
||||
#endif /* LOSCFG_KERNEL_TRACE == 1 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
590
components/trace/los_trace.h
Normal file
590
components/trace/los_trace.h
Normal file
@@ -0,0 +1,590 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup los_trace Trace
|
||||
* @ingroup kernel
|
||||
*/
|
||||
|
||||
#ifndef _LOS_TRACE_H
|
||||
#define _LOS_TRACE_H
|
||||
|
||||
#include "los_task.h"
|
||||
#include "trace_cnv.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if (LOSCFG_TRACE_CONTROL_AGENT == 1)
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* Trace Control agent task's priority.
|
||||
*/
|
||||
#define LOSCFG_TRACE_TASK_PRIORITY 2
|
||||
#endif
|
||||
|
||||
#define LOSCFG_TRACE_OBJ_MAX_NAME_SIZE LOS_TASK_NAMELEN
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* Trace records the max number of objects(kernel object, like tasks), range is [0, LOSCFG_BASE_CORE_TSK_LIMIT].
|
||||
* if set to 0, trace will not record any object.
|
||||
*/
|
||||
#define LOSCFG_TRACE_OBJ_MAX_NUM 0
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* Trace tlv encode buffer size, the buffer is used to encode one piece raw frame to tlv message in online mode.
|
||||
*/
|
||||
#define LOSCFG_TRACE_TLV_BUF_SIZE 100
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* Trace error code: init trace failed.
|
||||
*
|
||||
* Value: 0x02001400
|
||||
*
|
||||
* Solution: Follow the trace State Machine.
|
||||
*/
|
||||
#define LOS_ERRNO_TRACE_ERROR_STATUS LOS_ERRNO_OS_ERROR(LOS_MOD_TRACE, 0x00)
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* Trace error code: Insufficient memory for trace buf init.
|
||||
*
|
||||
* Value: 0x02001401
|
||||
*
|
||||
* Solution: Expand the configured system memory or decrease the value defined by LOS_TRACE_BUFFER_SIZE.
|
||||
*/
|
||||
#define LOS_ERRNO_TRACE_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_TRACE, 0x01)
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* Trace error code: Insufficient memory for trace struct.
|
||||
*
|
||||
* Value: 0x02001402
|
||||
*
|
||||
* Solution: Increase trace buffer's size.
|
||||
*/
|
||||
#define LOS_ERRNO_TRACE_BUF_TOO_SMALL LOS_ERRNO_OS_ERROR(LOS_MOD_TRACE, 0x02)
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* Trace state.
|
||||
*/
|
||||
enum TraceState {
|
||||
TRACE_UNINIT = 0, /**< trace isn't inited */
|
||||
TRACE_INITED, /**< trace is inited but not started yet */
|
||||
TRACE_STARTED, /**< trace is started and system is tracing */
|
||||
TRACE_STOPED, /**< trace is stopped */
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* Trace mask is used to filter events in runtime. Each mask keep only one unique bit to 1, and user can define own
|
||||
* module's trace mask.
|
||||
*/
|
||||
typedef enum {
|
||||
TRACE_SYS_FLAG = 0x10,
|
||||
TRACE_HWI_FLAG = 0x20,
|
||||
TRACE_TASK_FLAG = 0x40,
|
||||
TRACE_SWTMR_FLAG = 0x80,
|
||||
TRACE_MEM_FLAG = 0x100,
|
||||
TRACE_QUE_FLAG = 0x200,
|
||||
TRACE_EVENT_FLAG = 0x400,
|
||||
TRACE_SEM_FLAG = 0x800,
|
||||
TRACE_MUX_FLAG = 0x1000,
|
||||
|
||||
TRACE_MAX_FLAG = 0x80000000,
|
||||
TRACE_USER_DEFAULT_FLAG = 0xFFFFFFF0,
|
||||
} LOS_TRACE_MASK;
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* Trace event type which indicate the exactly happend events, user can define own module's event type like
|
||||
* TRACE_#MODULE#_FLAG | NUMBER.
|
||||
* 28 4
|
||||
* 0 0 0 0 0 0 0 0 X X X X X X X X 0 0 0 0 0 0
|
||||
* | | |
|
||||
* trace_module_flag number
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
/* 0x10~0x1F */
|
||||
SYS_ERROR = TRACE_SYS_FLAG | 0,
|
||||
SYS_START = TRACE_SYS_FLAG | 1,
|
||||
SYS_STOP = TRACE_SYS_FLAG | 2,
|
||||
|
||||
/* 0x20~0x2F */
|
||||
HWI_CREATE = TRACE_HWI_FLAG | 0,
|
||||
HWI_CREATE_SHARE = TRACE_HWI_FLAG | 1,
|
||||
HWI_DELETE = TRACE_HWI_FLAG | 2,
|
||||
HWI_DELETE_SHARE = TRACE_HWI_FLAG | 3,
|
||||
HWI_RESPONSE_IN = TRACE_HWI_FLAG | 4,
|
||||
HWI_RESPONSE_OUT = TRACE_HWI_FLAG | 5,
|
||||
HWI_ENABLE = TRACE_HWI_FLAG | 6,
|
||||
HWI_DISABLE = TRACE_HWI_FLAG | 7,
|
||||
HWI_TRIGGER = TRACE_HWI_FLAG | 8,
|
||||
HWI_SETPRI = TRACE_HWI_FLAG | 9,
|
||||
HWI_CLEAR = TRACE_HWI_FLAG | 10,
|
||||
HWI_SETAFFINITY = TRACE_HWI_FLAG | 11,
|
||||
HWI_SENDIPI = TRACE_HWI_FLAG | 12,
|
||||
|
||||
/* 0x40~0x4F */
|
||||
TASK_CREATE = TRACE_TASK_FLAG | 0,
|
||||
TASK_PRIOSET = TRACE_TASK_FLAG | 1,
|
||||
TASK_DELETE = TRACE_TASK_FLAG | 2,
|
||||
TASK_SUSPEND = TRACE_TASK_FLAG | 3,
|
||||
TASK_RESUME = TRACE_TASK_FLAG | 4,
|
||||
TASK_SWITCH = TRACE_TASK_FLAG | 5,
|
||||
TASK_SIGNAL = TRACE_TASK_FLAG | 6,
|
||||
|
||||
/* 0x80~0x8F */
|
||||
SWTMR_CREATE = TRACE_SWTMR_FLAG | 0,
|
||||
SWTMR_DELETE = TRACE_SWTMR_FLAG | 1,
|
||||
SWTMR_START = TRACE_SWTMR_FLAG | 2,
|
||||
SWTMR_STOP = TRACE_SWTMR_FLAG | 3,
|
||||
SWTMR_EXPIRED = TRACE_SWTMR_FLAG | 4,
|
||||
|
||||
/* 0x100~0x10F */
|
||||
MEM_ALLOC = TRACE_MEM_FLAG | 0,
|
||||
MEM_ALLOC_ALIGN = TRACE_MEM_FLAG | 1,
|
||||
MEM_REALLOC = TRACE_MEM_FLAG | 2,
|
||||
MEM_FREE = TRACE_MEM_FLAG | 3,
|
||||
MEM_INFO_REQ = TRACE_MEM_FLAG | 4,
|
||||
MEM_INFO = TRACE_MEM_FLAG | 5,
|
||||
|
||||
/* 0x200~0x20F */
|
||||
QUEUE_CREATE = TRACE_QUE_FLAG | 0,
|
||||
QUEUE_DELETE = TRACE_QUE_FLAG | 1,
|
||||
QUEUE_RW = TRACE_QUE_FLAG | 2,
|
||||
|
||||
/* 0x400~0x40F */
|
||||
EVENT_CREATE = TRACE_EVENT_FLAG | 0,
|
||||
EVENT_DELETE = TRACE_EVENT_FLAG | 1,
|
||||
EVENT_READ = TRACE_EVENT_FLAG | 2,
|
||||
EVENT_WRITE = TRACE_EVENT_FLAG | 3,
|
||||
EVENT_CLEAR = TRACE_EVENT_FLAG | 4,
|
||||
|
||||
/* 0x800~0x80F */
|
||||
SEM_CREATE = TRACE_SEM_FLAG | 0,
|
||||
SEM_DELETE = TRACE_SEM_FLAG | 1,
|
||||
SEM_PEND = TRACE_SEM_FLAG | 2,
|
||||
SEM_POST = TRACE_SEM_FLAG | 3,
|
||||
|
||||
/* 0x1000~0x100F */
|
||||
MUX_CREATE = TRACE_MUX_FLAG | 0,
|
||||
MUX_DELETE = TRACE_MUX_FLAG | 1,
|
||||
MUX_PEND = TRACE_MUX_FLAG | 2,
|
||||
MUX_POST = TRACE_MUX_FLAG | 3,
|
||||
} LOS_TRACE_TYPE;
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* struct to store the trace config information.
|
||||
*/
|
||||
typedef struct {
|
||||
UINT32 bigLittleEndian; /**< big little endian flag */
|
||||
UINT32 clockFreq; /**< system clock frequency */
|
||||
UINT32 version; /**< trace version */
|
||||
} TraceBaseHeaderInfo;
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* struct to store the event infomation
|
||||
*/
|
||||
typedef struct {
|
||||
UINT32 eventType; /**< event type */
|
||||
UINT32 curTask; /**< current running task */
|
||||
UINT64 curTime; /**< current timestamp */
|
||||
UINTPTR identity; /**< subject of the event description */
|
||||
#if (LOSCFG_TRACE_FRAME_CORE_MSG == 1)
|
||||
struct CoreStatus {
|
||||
UINT32 cpuId : 8, /**< cpuid */
|
||||
hwiActive : 4, /**< whether is in hwi response */
|
||||
taskLockCnt : 4, /**< task lock count */
|
||||
paramCount : 4, /**< event frame params' number */
|
||||
reserves : 12; /**< reserves */
|
||||
} core;
|
||||
#endif
|
||||
|
||||
#if (LOSCFG_TRACE_FRAME_EVENT_COUNT == 1)
|
||||
UINT32 eventCount; /**< the sequence of happend events */
|
||||
#endif
|
||||
|
||||
UINTPTR params[LOSCFG_TRACE_FRAME_MAX_PARAMS]; /**< event frame's params */
|
||||
} TraceEventFrame;
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* struct to store the kernel obj information, we defined task as kernel obj in this system.
|
||||
*/
|
||||
typedef struct {
|
||||
UINT32 id; /**< kernel obj's id */
|
||||
UINT32 prio; /**< kernel obj's priority */
|
||||
CHAR name[LOSCFG_TRACE_OBJ_MAX_NAME_SIZE]; /**< kernel obj's name */
|
||||
} ObjData;
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* struct to store the trace data.
|
||||
*/
|
||||
typedef struct {
|
||||
TraceBaseHeaderInfo baseInfo; /**< basic info, include bigLittleEndian flag, system clock freq */
|
||||
UINT16 totalLen; /**< trace data's total length */
|
||||
UINT16 objSize; /**< sizeof #ObjData */
|
||||
UINT16 frameSize; /**< sizeof #TraceEventFrame */
|
||||
UINT16 objOffset; /**< the offset of the first obj data to record beginning */
|
||||
UINT16 frameOffset; /**< the offset of the first event frame data to record beginning */
|
||||
} OfflineHead;
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* @brief Define the type of trace hardware interrupt filter hook function.
|
||||
*
|
||||
* @par Description:
|
||||
* User can register fliter function by LOS_TraceHwiFilterHookReg to filter hardware interrupt events. Return true if
|
||||
* user don't need trace the certain number.
|
||||
*
|
||||
* @attention
|
||||
* None.
|
||||
*
|
||||
* @param hwiNum [IN] Type #UINT32. The hardware interrupt number.
|
||||
* @retval #TRUE 0x00000001: Not record the certain number.
|
||||
* @retval #FALSE 0x00000000: Need record the certain number.
|
||||
*
|
||||
* @par Dependency:
|
||||
* <ul><li>los_trace.h: the header file that contains the API declaration.</li></ul>
|
||||
*/
|
||||
typedef BOOL (*TRACE_HWI_FILTER_HOOK)(UINT32 hwiNum);
|
||||
|
||||
typedef VOID (*TRACE_EVENT_HOOK)(UINT32 eventType, UINTPTR identity, const UINTPTR *params, UINT16 paramCount);
|
||||
extern TRACE_EVENT_HOOK g_traceEventHook;
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* Trace event params:
|
||||
1. Configure the macro without parameters so as not to record events of this type;
|
||||
2. Configure the macro at least with one parameter to record this type of event;
|
||||
3. User can delete unnecessary parameters which defined in corresponding marco;
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>The first param is treat as key, keep at least this param if you want trace this event.</li>
|
||||
* <li>All parameters were treated as UINTPTR.</li>
|
||||
* </ul>
|
||||
* eg. Trace a event as:
|
||||
* #define TASK_PRIOSET_PARAMS(taskId, taskStatus, oldPrio, newPrio) taskId, taskStatus, oldPrio, newPrio
|
||||
* eg. Not Trace a event as:
|
||||
* #define TASK_PRIOSET_PARAMS(taskId, taskStatus, oldPrio, newPrio)
|
||||
* eg. Trace only you need parmas as:
|
||||
* #define TASK_PRIOSET_PARAMS(taskId, taskStatus, oldPrio, newPrio) taskId
|
||||
*/
|
||||
#define TASK_SWITCH_PARAMS(taskId, oldPriority, oldTaskStatus, newPriority, newTaskStatus) \
|
||||
taskId, oldPriority, oldTaskStatus, newPriority, newTaskStatus
|
||||
#define TASK_PRIOSET_PARAMS(taskId, taskStatus, oldPrio, newPrio) taskId, taskStatus, oldPrio, newPrio
|
||||
#define TASK_CREATE_PARAMS(taskId, taskStatus, prio) taskId, taskStatus, prio
|
||||
#define TASK_DELETE_PARAMS(taskId, taskStatus, usrStack) taskId, taskStatus, usrStack
|
||||
#define TASK_SUSPEND_PARAMS(taskId, taskStatus, runTaskId) taskId, taskStatus, runTaskId
|
||||
#define TASK_RESUME_PARAMS(taskId, taskStatus, prio) taskId, taskStatus, prio
|
||||
#define TASK_SIGNAL_PARAMS(taskId, signal, schedFlag) // taskId, signal, schedFlag
|
||||
|
||||
#define SWTMR_START_PARAMS(swtmrId, mode, interval) swtmrId, mode, interval
|
||||
#define SWTMR_DELETE_PARAMS(swtmrId) swtmrId
|
||||
#define SWTMR_EXPIRED_PARAMS(swtmrId) swtmrId
|
||||
#define SWTMR_STOP_PARAMS(swtmrId) swtmrId
|
||||
#define SWTMR_CREATE_PARAMS(swtmrId) swtmrId
|
||||
|
||||
#define HWI_CREATE_PARAMS(hwiNum, hwiPrio, hwiMode, hwiHandler) hwiNum, hwiPrio, hwiMode, hwiHandler
|
||||
#define HWI_CREATE_SHARE_PARAMS(hwiNum, pDevId, ret) hwiNum, pDevId, ret
|
||||
#define HWI_DELETE_PARAMS(hwiNum) hwiNum
|
||||
#define HWI_DELETE_SHARE_PARAMS(hwiNum, pDevId, ret) hwiNum, pDevId, ret
|
||||
#define HWI_RESPONSE_IN_PARAMS(hwiNum) hwiNum
|
||||
#define HWI_RESPONSE_OUT_PARAMS(hwiNum) hwiNum
|
||||
#define HWI_ENABLE_PARAMS(hwiNum) hwiNum
|
||||
#define HWI_DISABLE_PARAMS(hwiNum) hwiNum
|
||||
#define HWI_TRIGGER_PARAMS(hwiNum) hwiNum
|
||||
#define HWI_SETPRI_PARAMS(hwiNum, priority) hwiNum, priority
|
||||
#define HWI_CLEAR_PARAMS(hwiNum) hwiNum
|
||||
#define HWI_SETAFFINITY_PARAMS(hwiNum, cpuMask) hwiNum, cpuMask
|
||||
#define HWI_SENDIPI_PARAMS(hwiNum, cpuMask) hwiNum, cpuMask
|
||||
|
||||
#define EVENT_CREATE_PARAMS(eventCB) eventCB
|
||||
#define EVENT_DELETE_PARAMS(eventCB, delRetCode) eventCB, delRetCode
|
||||
#define EVENT_READ_PARAMS(eventCB, eventId, mask, mode, timeout) \
|
||||
eventCB, eventId, mask, mode, timeout
|
||||
#define EVENT_WRITE_PARAMS(eventCB, eventId, events) eventCB, eventId, events
|
||||
#define EVENT_CLEAR_PARAMS(eventCB, eventId, events) eventCB, eventId, events
|
||||
|
||||
#define QUEUE_CREATE_PARAMS(queueId, queueSz, itemSz, queueAddr, memType) \
|
||||
queueId, queueSz, itemSz, queueAddr, memType
|
||||
#define QUEUE_DELETE_PARAMS(queueId, state, readable) queueId, state, readable
|
||||
#define QUEUE_RW_PARAMS(queueId, queueSize, bufSize, operateType, readable, writeable, timeout) \
|
||||
queueId, queueSize, bufSize, operateType, readable, writeable, timeout
|
||||
|
||||
#define SEM_CREATE_PARAMS(semId, type, count) semId, type, count
|
||||
#define SEM_DELETE_PARAMS(semId, delRetCode) semId, delRetCode
|
||||
#define SEM_PEND_PARAMS(semId, count, timeout) semId, count, timeout
|
||||
#define SEM_POST_PARAMS(semId, type, count) semId, type, count
|
||||
|
||||
#define MUX_CREATE_PARAMS(muxId) muxId
|
||||
#define MUX_DELETE_PARAMS(muxId, state, count, owner) muxId, state, count, owner
|
||||
#define MUX_PEND_PARAMS(muxId, count, owner, timeout) muxId, count, owner, timeout
|
||||
#define MUX_POST_PARAMS(muxId, count, owner) muxId, count, owner
|
||||
|
||||
#define MEM_ALLOC_PARAMS(pool, ptr, size) pool, ptr, size
|
||||
#define MEM_ALLOC_ALIGN_PARAMS(pool, ptr, size, boundary) pool, ptr, size, boundary
|
||||
#define MEM_REALLOC_PARAMS(pool, ptr, size) pool, ptr, size
|
||||
#define MEM_FREE_PARAMS(pool, ptr) pool, ptr
|
||||
#define MEM_INFO_REQ_PARAMS(pool) pool
|
||||
#define MEM_INFO_PARAMS(pool, usedSize, freeSize) pool, usedSize, freeSize
|
||||
|
||||
#define SYS_ERROR_PARAMS(errno) errno
|
||||
|
||||
#if (LOSCFG_KERNEL_TRACE == 1)
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* @brief Trace static code stub.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to instrument trace code stub in source code, to track events.
|
||||
* @attention
|
||||
* None.
|
||||
*
|
||||
* @param TYPE [IN] Type #LOS_TRACE_TYPE. The event type.
|
||||
* @param IDENTITY [IN] Type #UINTPTR. The subject of this event description.
|
||||
* @param ... [IN] Type #UINTPTR. This piece of event's params.
|
||||
* @retval None.
|
||||
*
|
||||
* @par Dependency:
|
||||
* <ul><li>los_trace.h: the header file that contains the API declaration.</li></ul>
|
||||
*/
|
||||
#define LOS_TRACE(TYPE, IDENTITY, ...) \
|
||||
do { \
|
||||
UINTPTR _inner[] = {0, TYPE##_PARAMS((UINTPTR)IDENTITY, ##__VA_ARGS__)}; \
|
||||
UINTPTR _n = sizeof(_inner) / sizeof(UINTPTR); \
|
||||
if ((_n > 1) && (g_traceEventHook != NULL)) { \
|
||||
g_traceEventHook(TYPE, _inner[1], _n > 2 ? &_inner[2] : NULL, _n - 2); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define LOS_TRACE(TYPE, ...)
|
||||
#endif
|
||||
|
||||
#if (LOSCFG_KERNEL_TRACE == 1)
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* @brief Trace static easier user-defined code stub.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to instrument user-defined trace code stub in source code, to track events simply.
|
||||
* @attention
|
||||
* None.
|
||||
*
|
||||
* @param TYPE [IN] Type #UINT32. The event type, only low 4 bits take effect.
|
||||
* @param IDENTITY [IN] Type #UINTPTR. The subject of this event description.
|
||||
* @param ... [IN] Type #UINTPTR. This piece of event's params.
|
||||
* @retval None.
|
||||
*
|
||||
* @par Dependency:
|
||||
* <ul><li>los_trace.h: the header file that contains the API declaration.</li></ul>
|
||||
*/
|
||||
#define LOS_TRACE_EASY(TYPE, IDENTITY, ...) \
|
||||
do { \
|
||||
UINTPTR _inner[] = {0, ##__VA_ARGS__}; \
|
||||
UINTPTR _n = sizeof(_inner) / sizeof(UINTPTR); \
|
||||
if (g_traceEventHook != NULL) { \
|
||||
g_traceEventHook(TRACE_USER_DEFAULT_FLAG | TYPE, (UINTPTR)IDENTITY, _n > 1 ? &_inner[1] : NULL, _n - 1); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define LOS_TRACE_EASY(...)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* @brief Start trace.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to start trace.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>Start trace</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param None.
|
||||
* @retval #LOS_ERRNO_TRACE_ERROR_STATUS 0x02001400: Trace start failed.
|
||||
* @retval #LOS_OK 0x00000000: Trace start success.
|
||||
*
|
||||
* @par Dependency:
|
||||
* <ul><li>los_trace.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see LOS_TraceStart
|
||||
*/
|
||||
extern UINT32 LOS_TraceStart(VOID);
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* @brief Stop trace sample.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to start trace sample.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>Stop trace sample</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param None.
|
||||
* @retval #None.
|
||||
*
|
||||
* @par Dependency:
|
||||
* <ul><li>los_trace.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see LOS_TraceStop
|
||||
*/
|
||||
extern VOID LOS_TraceStop(VOID);
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* @brief Clear the trace buf.
|
||||
*
|
||||
* @par Description:
|
||||
* Clear the event frames in trace buf only at offline mode.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>This API can be called only after that trace buffer has been established.</li>
|
||||
* Otherwise, the trace will be failed.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param None.
|
||||
* @retval #NA
|
||||
* @par Dependency:
|
||||
* <ul><li>los_trace.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see LOS_TraceReset
|
||||
*/
|
||||
extern VOID LOS_TraceReset(VOID);
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* @brief Set trace event mask.
|
||||
*
|
||||
* @par Description:
|
||||
* Set trace event mask.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>Set trace event filter mask.</li>
|
||||
* <li>The Default mask is (TRACE_HWI_FLAG | TRACE_TASK_FLAG), stands for switch on task and hwi events.</li>
|
||||
* <li>Customize mask according to the type defined in enum LOS_TRACE_MASK to switch on corresponding module's
|
||||
* trace.</li>
|
||||
* <li>The system's trace mask will be overrode by the input parameter.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param mask [IN] Type #UINT32. The mask used to filter events of LOS_TRACE_MASK.
|
||||
* @retval #NA.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_trace.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see LOS_TraceEventMaskSet
|
||||
*/
|
||||
extern VOID LOS_TraceEventMaskSet(UINT32 mask);
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* @brief Offline trace buffer display.
|
||||
*
|
||||
* @par Description:
|
||||
* Display trace buf data only at offline mode.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>This API can be called only after that trace stopped. Otherwise the trace dump will be failed.</li>
|
||||
* <li>Trace data will be send to pipeline when user set toClient = TRUE. Otherwise it will be formatted and printed
|
||||
* out.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param toClient [IN] Type #BOOL. Whether send trace data to Client through pipeline.
|
||||
* @retval #NA
|
||||
*
|
||||
* @par Dependency:
|
||||
* <ul><li>los_trace.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see LOS_TraceRecordDump
|
||||
*/
|
||||
extern VOID LOS_TraceRecordDump(BOOL toClient);
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* @brief Offline trace buffer export.
|
||||
*
|
||||
* @par Description:
|
||||
* Return the trace buf only at offline mode.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>This API can be called only after that trace buffer has been established. </li>
|
||||
* <li>The return buffer's address is a critical resource, user can only ready.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param NA
|
||||
* @retval #OfflineHead* The trace buffer's address, analyze this buffer according to the structure of
|
||||
* OfflineHead.
|
||||
*
|
||||
* @par Dependency:
|
||||
* <ul><li>los_trace.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see LOS_TraceRecordGet
|
||||
*/
|
||||
extern OfflineHead *LOS_TraceRecordGet(VOID);
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* @brief Hwi num fliter hook.
|
||||
*
|
||||
* @par Description:
|
||||
* Hwi fliter function.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>Filter the hwi events by hwi num</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param hook [IN] Type #TRACE_HWI_FILTER_HOOK. The user defined hook for hwi num filter,
|
||||
* the hook should return true if you don't want trace this hwi num.
|
||||
* @retval #None
|
||||
* @par Dependency:
|
||||
* <ul><li>los_trace.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see LOS_TraceHwiFilterHookReg
|
||||
*/
|
||||
extern VOID LOS_TraceHwiFilterHookReg(TRACE_HWI_FILTER_HOOK hook);
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_TRACE_H */
|
||||
161
components/trace/los_trace_pri.h
Normal file
161
components/trace/los_trace_pri.h
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_TRACE_PRI_H
|
||||
#define _LOS_TRACE_PRI_H
|
||||
|
||||
#include "los_trace.h"
|
||||
#include "los_task.h"
|
||||
#include "los_debug.h"
|
||||
#include "los_interrupt.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if (LOSCFG_TRACE_CONTROL_AGENT == 1)
|
||||
#define TRACE_CMD_END_CHAR 0xD
|
||||
#endif
|
||||
|
||||
#define TRACE_ERROR PRINT_ERR
|
||||
#define TRACE_MODE_OFFLINE 0
|
||||
#define TRACE_MODE_ONLINE 1
|
||||
|
||||
/* just task and hwi were traced */
|
||||
#define TRACE_DEFAULT_MASK (TRACE_HWI_FLAG | TRACE_TASK_FLAG)
|
||||
#define TRACE_CTL_MAGIC_NUM 0xDEADBEEF
|
||||
#define TRACE_BIGLITTLE_WORD 0x12345678
|
||||
#define TRACE_VERSION(MODE) (0xFFFFFFFF & (MODE))
|
||||
#define TRACE_MASK_COMBINE(c1, c2, c3, c4) (((c1) << 24) | ((c2) << 16) | ((c3) << 8) | (c4))
|
||||
|
||||
#define TRACE_GET_MODE_FLAG(type) ((type) & 0xFFFFFFF0)
|
||||
|
||||
#if (LOSCFG_KERNEL_SMP == 1)
|
||||
extern SPIN_LOCK_S g_traceSpin;
|
||||
#define TRACE_LOCK(state) LOS_SpinLockSave(&g_traceSpin, &(state))
|
||||
#define TRACE_UNLOCK(state) LOS_SpinUnlockRestore(&g_traceSpin, (state))
|
||||
#else
|
||||
#define TRACE_LOCK(state) (state) = LOS_IntLock()
|
||||
#define TRACE_UNLOCK(state) LOS_IntRestore(state)
|
||||
#endif
|
||||
|
||||
typedef VOID (*TRACE_DUMP_HOOK)(BOOL toClient);
|
||||
extern TRACE_DUMP_HOOK g_traceDumpHook;
|
||||
|
||||
enum TraceCmd {
|
||||
TRACE_CMD_START = 1,
|
||||
TRACE_CMD_STOP,
|
||||
TRACE_CMD_SET_EVENT_MASK,
|
||||
TRACE_CMD_RECODE_DUMP,
|
||||
TRACE_CMD_MAX_CODE,
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* struct to store the trace cmd from traceClient.
|
||||
*/
|
||||
typedef struct {
|
||||
UINT8 cmd;
|
||||
UINT8 param1;
|
||||
UINT8 param2;
|
||||
UINT8 param3;
|
||||
UINT8 param4;
|
||||
UINT8 param5;
|
||||
UINT8 end;
|
||||
} TraceClientCmd;
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* struct to store the event infomation
|
||||
*/
|
||||
typedef struct {
|
||||
UINT32 cmd; /* trace start or stop cmd */
|
||||
UINT32 param; /* magic numb stand for notify msg */
|
||||
} TraceNotifyFrame;
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* struct to store the trace config information.
|
||||
*/
|
||||
typedef struct {
|
||||
struct WriteCtrl {
|
||||
UINT16 curIndex; /* The current record index */
|
||||
UINT16 maxRecordCount; /* The max num of track items */
|
||||
UINT16 curObjIndex; /* The current obj index */
|
||||
UINT16 maxObjCount; /* The max num of obj index */
|
||||
ObjData *objBuf; /* Pointer to obj info data */
|
||||
TraceEventFrame *frameBuf; /* Pointer to the track items */
|
||||
} ctrl;
|
||||
OfflineHead *head;
|
||||
} TraceOfflineHeaderInfo;
|
||||
|
||||
extern UINT32 OsTraceInit(VOID);
|
||||
extern UINT32 OsTraceGetMaskTid(UINT32 taskId);
|
||||
extern VOID OsTraceSetObj(ObjData *obj, const LosTaskCB *tcb);
|
||||
extern VOID OsTraceWriteOrSendEvent(const TraceEventFrame *frame);
|
||||
extern VOID OsTraceObjAdd(UINT32 eventType, UINT32 taskId);
|
||||
extern BOOL OsTraceIsEnable(VOID);
|
||||
extern OfflineHead *OsTraceRecordGet(VOID);
|
||||
|
||||
#if (LOSCFG_RECORDER_MODE_ONLINE == 1)
|
||||
extern VOID OsTraceSendHead(VOID);
|
||||
extern VOID OsTraceSendObjTable(VOID);
|
||||
extern VOID OsTraceSendNotify(UINT32 type, UINT32 value);
|
||||
|
||||
#define OsTraceNotifyStart() do { \
|
||||
OsTraceSendNotify(SYS_START, TRACE_CTL_MAGIC_NUM); \
|
||||
OsTraceSendHead(); \
|
||||
OsTraceSendObjTable(); \
|
||||
} while (0)
|
||||
|
||||
#define OsTraceNotifyStop() do { \
|
||||
OsTraceSendNotify(SYS_STOP, TRACE_CTL_MAGIC_NUM); \
|
||||
} while (0)
|
||||
|
||||
#define OsTraceReset()
|
||||
#define OsTraceRecordDump(toClient)
|
||||
#else
|
||||
extern UINT32 OsTraceBufInit(UINT32 size);
|
||||
extern VOID OsTraceReset(VOID);
|
||||
extern VOID OsTraceRecordDump(BOOL toClient);
|
||||
#define OsTraceNotifyStart()
|
||||
#define OsTraceNotifyStop()
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_TRACE_PRI_H */
|
||||
101
components/trace/pipeline/serial/trace_pipeline_serial.c
Normal file
101
components/trace/pipeline/serial/trace_pipeline_serial.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "trace_pipeline_serial.h"
|
||||
#include "trace_pipeline.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if (LOSCFG_TRACE_CONTROL_AGENT == 1)
|
||||
UINT32 SerialPipelineInit(VOID)
|
||||
{
|
||||
return uart_hwiCreate();
|
||||
}
|
||||
|
||||
UINT32 SerialDataReceive(UINT8 *data, UINT32 size, UINT32 timeout)
|
||||
{
|
||||
return uart_read(data, size, timeout);
|
||||
}
|
||||
|
||||
UINT32 SerialWait(VOID)
|
||||
{
|
||||
return uart_wait_adapt();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
UINT32 SerialPipelineInit(VOID)
|
||||
{
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
UINT32 SerialDataReceive(UINT8 *data, UINT32 size, UINT32 timeout)
|
||||
{
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
UINT32 SerialWait(VOID)
|
||||
{
|
||||
return LOS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
VOID SerialDataSend(UINT16 len, UINT8 *data)
|
||||
{
|
||||
UINT32 i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
UART_PUTC(data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC const TracePipelineOps g_serialOps = {
|
||||
.init = SerialPipelineInit,
|
||||
.dataSend = SerialDataSend,
|
||||
.dataRecv = SerialDataReceive,
|
||||
.wait = SerialWait,
|
||||
};
|
||||
|
||||
UINT32 OsTracePipelineInit(VOID)
|
||||
{
|
||||
OsTracePipelineReg(&g_serialOps);
|
||||
return g_serialOps.init();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
53
components/trace/pipeline/serial/trace_pipeline_serial.h
Normal file
53
components/trace/pipeline/serial/trace_pipeline_serial.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _TRACE_PIPELINE_SERIAL_H
|
||||
#define _TRACE_PIPELINE_SERIAL_H
|
||||
|
||||
#include "los_compiler.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
extern INT32 uart_putc(CHAR c);
|
||||
|
||||
#define UART_PUTC(c) uart_putc((c))
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _TRACE_PIPELINE_SERIAL_H */
|
||||
162
components/trace/pipeline/trace_pipeline.c
Normal file
162
components/trace/pipeline/trace_pipeline.c
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "trace_pipeline.h"
|
||||
#include "trace_tlv.h"
|
||||
#include "los_trace_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if (LOSCFG_KERNEL_SMP == 1)
|
||||
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_pipeSpin);
|
||||
#define PIPE_LOCK(state) LOS_SpinLockSave(&g_pipeSpin, &(state))
|
||||
#define PIPE_UNLOCK(state) LOS_SpinUnlockRestore(&g_pipeSpin, (state))
|
||||
#else
|
||||
#define PIPE_LOCK(state) (state) = LOS_IntLock()
|
||||
#define PIPE_UNLOCK(state) LOS_IntRestore(state)
|
||||
#endif
|
||||
|
||||
STATIC TlvTable g_traceTlvTblNotify[] = {
|
||||
{ CMD, LOS_OFF_SET_OF(TraceNotifyFrame, cmd), sizeof(UINT32) },
|
||||
{ PARAMS, LOS_OFF_SET_OF(TraceNotifyFrame, param), sizeof(UINT32) },
|
||||
{ TRACE_TLV_TYPE_NULL, 0, 0 },
|
||||
};
|
||||
|
||||
STATIC TlvTable g_traceTlvTblHead[] = {
|
||||
{ ENDIAN, LOS_OFF_SET_OF(TraceBaseHeaderInfo, bigLittleEndian), sizeof(UINT32) },
|
||||
{ VERSION, LOS_OFF_SET_OF(TraceBaseHeaderInfo, version), sizeof(UINT32) },
|
||||
{ CLOCK_FREQ, LOS_OFF_SET_OF(TraceBaseHeaderInfo, clockFreq), sizeof(UINT32) },
|
||||
{ TRACE_TLV_TYPE_NULL, 0, 0 },
|
||||
};
|
||||
|
||||
STATIC TlvTable g_traceTlvTblObj[] = {
|
||||
{ ADDR, LOS_OFF_SET_OF(ObjData, id), sizeof(UINT32) },
|
||||
{ PRIO, LOS_OFF_SET_OF(ObjData, prio), sizeof(UINT32) },
|
||||
{ NAME, LOS_OFF_SET_OF(ObjData, name), sizeof(CHAR) * LOSCFG_TRACE_OBJ_MAX_NAME_SIZE },
|
||||
{ TRACE_TLV_TYPE_NULL, 0, 0 },
|
||||
};
|
||||
|
||||
STATIC TlvTable g_traceTlvTblEvent[] = {
|
||||
#if (LOSCFG_TRACE_FRAME_CORE_MSG == 1)
|
||||
{ CORE, LOS_OFF_SET_OF(TraceEventFrame, core), sizeof(UINT32) },
|
||||
#endif
|
||||
{ EVENT_CODE, LOS_OFF_SET_OF(TraceEventFrame, eventType), sizeof(UINT32) },
|
||||
{ CUR_TIME, LOS_OFF_SET_OF(TraceEventFrame, curTime), sizeof(UINT64) },
|
||||
|
||||
#if (LOSCFG_TRACE_FRAME_EVENT_COUNT == 1)
|
||||
{ EVENT_COUNT, LOS_OFF_SET_OF(TraceEventFrame, eventCount), sizeof(UINT32) },
|
||||
#endif
|
||||
{ CUR_TASK, LOS_OFF_SET_OF(TraceEventFrame, curTask), sizeof(UINT32) },
|
||||
{ IDENTITY, LOS_OFF_SET_OF(TraceEventFrame, identity), sizeof(UINTPTR) },
|
||||
{ EVENT_PARAMS, LOS_OFF_SET_OF(TraceEventFrame, params), sizeof(UINTPTR) * LOSCFG_TRACE_FRAME_MAX_PARAMS },
|
||||
{ TRACE_TLV_TYPE_NULL, 0, 0 },
|
||||
};
|
||||
|
||||
STATIC TlvTable *g_traceTlvTbl[] = {
|
||||
g_traceTlvTblNotify,
|
||||
g_traceTlvTblHead,
|
||||
g_traceTlvTblObj,
|
||||
g_traceTlvTblEvent
|
||||
};
|
||||
|
||||
STATIC UINT32 DefaultPipelineInit(VOID)
|
||||
{
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC VOID DefaultDataSend(UINT16 len, UINT8 *data)
|
||||
{
|
||||
(VOID)len;
|
||||
(VOID)data;
|
||||
}
|
||||
|
||||
STATIC UINT32 DefaultDataReceive(UINT8 *data, UINT32 size, UINT32 timeout)
|
||||
{
|
||||
(VOID)data;
|
||||
(VOID)size;
|
||||
(VOID)timeout;
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC UINT32 DefaultWait(VOID)
|
||||
{
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC TracePipelineOps g_defaultOps = {
|
||||
.init = DefaultPipelineInit,
|
||||
.dataSend = DefaultDataSend,
|
||||
.dataRecv = DefaultDataReceive,
|
||||
.wait = DefaultWait,
|
||||
};
|
||||
|
||||
STATIC const TracePipelineOps *g_tracePipelineOps = &g_defaultOps;
|
||||
|
||||
VOID OsTracePipelineReg(const TracePipelineOps *ops)
|
||||
{
|
||||
g_tracePipelineOps = ops;
|
||||
}
|
||||
|
||||
VOID OsTraceDataSend(UINT8 type, UINT16 len, UINT8 *data)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINT8 outBuf[LOSCFG_TRACE_TLV_BUF_SIZE] = {0};
|
||||
|
||||
if ((type > TRACE_MSG_MAX) || (len > LOSCFG_TRACE_TLV_BUF_SIZE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
len = OsTraceDataEncode(type, g_traceTlvTbl[type], data, &outBuf[0], sizeof(outBuf));
|
||||
|
||||
PIPE_LOCK(intSave);
|
||||
g_tracePipelineOps->dataSend(len, &outBuf[0]);
|
||||
PIPE_UNLOCK(intSave);
|
||||
}
|
||||
|
||||
UINT32 OsTraceDataRecv(UINT8 *data, UINT32 size, UINT32 timeout)
|
||||
{
|
||||
return g_tracePipelineOps->dataRecv(data, size, timeout);
|
||||
}
|
||||
|
||||
UINT32 OsTraceDataWait(VOID)
|
||||
{
|
||||
return g_tracePipelineOps->wait();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
104
components/trace/pipeline/trace_pipeline.h
Normal file
104
components/trace/pipeline/trace_pipeline.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _TRACE_PIPELINE_H
|
||||
#define _TRACE_PIPELINE_H
|
||||
|
||||
#include "los_compiler.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct {
|
||||
UINT32 (*init)(VOID);
|
||||
VOID (*dataSend)(UINT16 len, UINT8 *data);
|
||||
UINT32 (*dataRecv)(UINT8 *data, UINT32 size, UINT32 timeout);
|
||||
UINT32 (*wait)(VOID);
|
||||
} TracePipelineOps;
|
||||
|
||||
/* used as tlv's tag */
|
||||
enum TraceMsgType {
|
||||
NOTIFY,
|
||||
HEAD,
|
||||
OBJ,
|
||||
EVENT,
|
||||
TRACE_MSG_MAX,
|
||||
};
|
||||
|
||||
enum TraceNotifySubType {
|
||||
CMD = 0x1,
|
||||
PARAMS,
|
||||
};
|
||||
|
||||
enum TraceHeadSubType {
|
||||
ENDIAN = 0x1,
|
||||
VERSION,
|
||||
OBJ_SIZE,
|
||||
OBJ_COUNT,
|
||||
CUR_INDEX,
|
||||
MAX_RECODE,
|
||||
CUR_OBJ_INDEX,
|
||||
CLOCK_FREQ,
|
||||
};
|
||||
|
||||
enum TraceObjSubType {
|
||||
ADDR = 0x1,
|
||||
PRIO,
|
||||
NAME,
|
||||
};
|
||||
|
||||
enum TraceEvtSubType {
|
||||
CORE = 0x1,
|
||||
EVENT_CODE,
|
||||
CUR_TIME,
|
||||
EVENT_COUNT,
|
||||
CUR_TASK,
|
||||
IDENTITY,
|
||||
EVENT_PARAMS,
|
||||
};
|
||||
|
||||
extern VOID OsTracePipelineReg(const TracePipelineOps *ops);
|
||||
extern UINT32 OsTracePipelineInit(VOID);
|
||||
|
||||
extern VOID OsTraceDataSend(UINT8 type, UINT16 len, UINT8 *data);
|
||||
extern UINT32 OsTraceDataRecv(UINT8 *data, UINT32 size, UINT32 timeout);
|
||||
extern UINT32 OsTraceDataWait(VOID);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _TRACE_PIPELINE_H */
|
||||
122
components/trace/pipeline/trace_tlv.c
Normal file
122
components/trace/pipeline/trace_tlv.c
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "trace_tlv.h"
|
||||
#include "securec.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define CRC_WIDTH 8
|
||||
#define CRC_POLY 0x1021
|
||||
#define CRC_TOPBIT 0x8000
|
||||
|
||||
STATIC UINT16 CalcCrc16(const UINT8 *buf, UINT32 len)
|
||||
{
|
||||
UINT32 i;
|
||||
UINT16 crc = 0;
|
||||
|
||||
for (; len > 0; len--) {
|
||||
crc = crc ^ (*buf++ << CRC_WIDTH);
|
||||
for (i = 0; i < CRC_WIDTH; i++) {
|
||||
if (crc & CRC_TOPBIT) {
|
||||
crc = (crc << 1) ^ CRC_POLY;
|
||||
} else {
|
||||
crc <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
STATIC UINT32 OsWriteTlv(UINT8 *tlvBuf, UINT8 type, UINT8 len, UINT8 *value)
|
||||
{
|
||||
TraceMsgTlvBody *body = (TraceMsgTlvBody *)tlvBuf;
|
||||
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
body->type = type;
|
||||
body->len = len;
|
||||
/* Do not check return value for performance, if copy failed, only this package will be discarded */
|
||||
(VOID)memcpy_s(body->value, len, value, len);
|
||||
return len + sizeof(body->type) + sizeof(body->len);
|
||||
}
|
||||
|
||||
STATIC UINT32 OsTlvEncode(const TlvTable *table, UINT8 *srcBuf, UINT8 *tlvBuf, INT32 tlvBufLen)
|
||||
{
|
||||
UINT32 len = 0;
|
||||
const TlvTable *tlvTableItem = table;
|
||||
|
||||
while (tlvTableItem->tag != TRACE_TLV_TYPE_NULL) {
|
||||
if ((len + tlvTableItem->elemSize + sizeof(UINT8) + sizeof(UINT8)) > tlvBufLen) {
|
||||
break;
|
||||
}
|
||||
len += OsWriteTlv(tlvBuf + len, tlvTableItem->tag, tlvTableItem->elemSize, srcBuf + tlvTableItem->elemOffset);
|
||||
tlvTableItem++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
UINT32 OsTraceDataEncode(UINT8 type, const TlvTable *table, UINT8 *src, UINT8 *dest, INT32 destLen)
|
||||
{
|
||||
UINT16 crc;
|
||||
INT32 len;
|
||||
INT32 tlvBufLen;
|
||||
UINT8 *tlvBuf = NULL;
|
||||
|
||||
TraceMsgTlvHead *head = (TraceMsgTlvHead *)dest;
|
||||
tlvBufLen = destLen - sizeof(TraceMsgTlvHead);
|
||||
|
||||
if ((tlvBufLen <= 0) || (table == NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
tlvBuf = dest + sizeof(TraceMsgTlvHead);
|
||||
len = OsTlvEncode(table, src, tlvBuf, tlvBufLen);
|
||||
crc = CalcCrc16(tlvBuf, len);
|
||||
|
||||
head->magicNum = TRACE_TLV_MSG_HEAD;
|
||||
head->msgType = type;
|
||||
head->len = len;
|
||||
head->crc = crc;
|
||||
return len + sizeof(TraceMsgTlvHead);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
97
components/trace/pipeline/trace_tlv.h
Normal file
97
components/trace/pipeline/trace_tlv.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _TRACE_TLV_H
|
||||
#define _TRACE_TLV_H
|
||||
|
||||
#include "los_compiler.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define TRACE_TLV_MSG_HEAD 0xFF
|
||||
#define TRACE_TLV_TYPE_NULL 0xFF
|
||||
|
||||
typedef struct {
|
||||
UINT8 magicNum;
|
||||
UINT8 msgType;
|
||||
UINT16 len;
|
||||
UINT16 crc;
|
||||
} TraceMsgTlvHead;
|
||||
|
||||
typedef struct {
|
||||
UINT8 type;
|
||||
UINT8 len;
|
||||
UINT8 value[];
|
||||
} TraceMsgTlvBody;
|
||||
|
||||
typedef struct {
|
||||
UINT8 tag;
|
||||
UINT8 elemOffset;
|
||||
UINT8 elemSize;
|
||||
} TlvTable;
|
||||
|
||||
/**
|
||||
* @ingroup los_trace
|
||||
* @brief Encode trace raw data.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to encode trace raw data to tlv data.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>Encade trace data</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param type [IN] Type #UINT8. The type stands for different struct of src data.
|
||||
* @param src [IN] Type #UINT8 *. The raw trace data.
|
||||
* @param table [IN] Type #const TlvTable *. The tlv table descript elemOffset and elemSize.
|
||||
* @param dest [OUT] Type #UINT8 *. The tlv data.
|
||||
* @param destLen [IN] Type #UINT8 *. The tlv buf max len.
|
||||
|
||||
* @retval #0 convert failed.
|
||||
* @retval #UINT32 convert success bytes.
|
||||
*
|
||||
* @par Dependency:
|
||||
* <ul><li>trace_tlv.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see LOS_TraceDataEncode
|
||||
*/
|
||||
extern UINT32 OsTraceDataEncode(UINT8 type, const TlvTable *table, UINT8 *src, UINT8 *dest, INT32 destLen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _TRACE_TLV_H */
|
||||
265
components/trace/trace_offline.c
Normal file
265
components/trace/trace_offline.c
Normal file
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_trace_pri.h"
|
||||
#include "trace_pipeline.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if (LOSCFG_RECORDER_MODE_OFFLINE == 1)
|
||||
#define BITS_NUM_FOR_TASK_ID 16
|
||||
|
||||
LITE_OS_SEC_BSS STATIC TraceOfflineHeaderInfo g_traceRecoder;
|
||||
LITE_OS_SEC_BSS STATIC UINT32 g_tidMask[LOSCFG_BASE_CORE_TSK_LIMIT] = {0};
|
||||
|
||||
UINT32 OsTraceGetMaskTid(UINT32 tid)
|
||||
{
|
||||
return tid | ((tid < LOSCFG_BASE_CORE_TSK_LIMIT) ? g_tidMask[tid] << BITS_NUM_FOR_TASK_ID : 0); /* tid < 65535 */
|
||||
}
|
||||
|
||||
UINT32 OsTraceBufInit(UINT32 size)
|
||||
{
|
||||
UINT32 headSize;
|
||||
VOID *buf = NULL;
|
||||
headSize = sizeof(OfflineHead) + sizeof(ObjData) * LOSCFG_TRACE_OBJ_MAX_NUM;
|
||||
if (size <= headSize) {
|
||||
TRACE_ERROR("trace buf size not enough than 0x%x\n", headSize);
|
||||
return LOS_ERRNO_TRACE_BUF_TOO_SMALL;
|
||||
}
|
||||
|
||||
buf = LOS_MemAlloc(m_aucSysMem0, size);
|
||||
if (buf == NULL) {
|
||||
return LOS_ERRNO_TRACE_NO_MEMORY;
|
||||
}
|
||||
|
||||
(VOID)memset_s(buf, size, 0, size);
|
||||
g_traceRecoder.head = (OfflineHead *)buf;
|
||||
g_traceRecoder.head->baseInfo.bigLittleEndian = TRACE_BIGLITTLE_WORD;
|
||||
g_traceRecoder.head->baseInfo.version = TRACE_VERSION(TRACE_MODE_OFFLINE);
|
||||
g_traceRecoder.head->baseInfo.clockFreq = OS_SYS_CLOCK;
|
||||
g_traceRecoder.head->objSize = sizeof(ObjData);
|
||||
g_traceRecoder.head->frameSize = sizeof(TraceEventFrame);
|
||||
g_traceRecoder.head->objOffset = sizeof(OfflineHead);
|
||||
g_traceRecoder.head->frameOffset = headSize;
|
||||
g_traceRecoder.head->totalLen = size;
|
||||
|
||||
g_traceRecoder.ctrl.curIndex = 0;
|
||||
g_traceRecoder.ctrl.curObjIndex = 0;
|
||||
g_traceRecoder.ctrl.maxObjCount = LOSCFG_TRACE_OBJ_MAX_NUM;
|
||||
g_traceRecoder.ctrl.maxRecordCount = (size - headSize) / sizeof(TraceEventFrame);
|
||||
g_traceRecoder.ctrl.objBuf = (ObjData *)((UINTPTR)buf + g_traceRecoder.head->objOffset);
|
||||
g_traceRecoder.ctrl.frameBuf = (TraceEventFrame *)((UINTPTR)buf + g_traceRecoder.head->frameOffset);
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
VOID OsTraceObjAdd(UINT32 eventType, UINT32 taskId)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINT32 index;
|
||||
ObjData *obj = NULL;
|
||||
|
||||
TRACE_LOCK(intSave);
|
||||
/* add obj begin */
|
||||
index = g_traceRecoder.ctrl.curObjIndex;
|
||||
if (index >= LOSCFG_TRACE_OBJ_MAX_NUM) { /* do nothing when config LOSCFG_TRACE_OBJ_MAX_NUM = 0 */
|
||||
TRACE_UNLOCK(intSave);
|
||||
return;
|
||||
}
|
||||
obj = &g_traceRecoder.ctrl.objBuf[index];
|
||||
|
||||
if (taskId < LOSCFG_BASE_CORE_TSK_LIMIT) {
|
||||
g_tidMask[taskId]++;
|
||||
}
|
||||
|
||||
OsTraceSetObj(obj, OS_TCB_FROM_TID(taskId));
|
||||
|
||||
g_traceRecoder.ctrl.curObjIndex++;
|
||||
if (g_traceRecoder.ctrl.curObjIndex >= g_traceRecoder.ctrl.maxObjCount) {
|
||||
g_traceRecoder.ctrl.curObjIndex = 0; /* turn around */
|
||||
}
|
||||
/* add obj end */
|
||||
TRACE_UNLOCK(intSave);
|
||||
}
|
||||
|
||||
VOID OsTraceWriteOrSendEvent(const TraceEventFrame *frame)
|
||||
{
|
||||
UINT16 index;
|
||||
UINT32 intSave;
|
||||
|
||||
TRACE_LOCK(intSave);
|
||||
index = g_traceRecoder.ctrl.curIndex;
|
||||
(VOID)memcpy_s(&g_traceRecoder.ctrl.frameBuf[index], sizeof(TraceEventFrame), frame, sizeof(TraceEventFrame));
|
||||
|
||||
g_traceRecoder.ctrl.curIndex++;
|
||||
if (g_traceRecoder.ctrl.curIndex >= g_traceRecoder.ctrl.maxRecordCount) {
|
||||
g_traceRecoder.ctrl.curIndex = 0;
|
||||
}
|
||||
TRACE_UNLOCK(intSave);
|
||||
}
|
||||
|
||||
VOID OsTraceReset(VOID)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINT32 bufLen;
|
||||
|
||||
TRACE_LOCK(intSave);
|
||||
bufLen = sizeof(TraceEventFrame) * g_traceRecoder.ctrl.maxRecordCount;
|
||||
(VOID)memset_s(g_traceRecoder.ctrl.frameBuf, bufLen, 0, bufLen);
|
||||
g_traceRecoder.ctrl.curIndex = 0;
|
||||
TRACE_UNLOCK(intSave);
|
||||
}
|
||||
|
||||
STATIC VOID OsTraceInfoObj(VOID)
|
||||
{
|
||||
UINT32 i;
|
||||
ObjData *obj = &g_traceRecoder.ctrl.objBuf[0];
|
||||
|
||||
if (g_traceRecoder.ctrl.maxObjCount > 0) {
|
||||
PRINTK("CurObjIndex = %u\n", g_traceRecoder.ctrl.curObjIndex);
|
||||
PRINTK("Index TaskID TaskPrio TaskName \n");
|
||||
for (i = 0; i < g_traceRecoder.ctrl.maxObjCount; i++, obj++) {
|
||||
PRINTK("%-7u 0x%-6x %-10u %s\n", i, obj->id, obj->prio, obj->name);
|
||||
}
|
||||
PRINTK("\n");
|
||||
}
|
||||
}
|
||||
|
||||
STATIC VOID OsTraceInfoEventTitle(VOID)
|
||||
{
|
||||
PRINTK("CurEvtIndex = %u\n", g_traceRecoder.ctrl.curIndex);
|
||||
|
||||
PRINTK("Index Time(cycles) EventType CurTask Identity ");
|
||||
#if (LOSCFG_TRACE_FRAME_CORE_MSG == 1)
|
||||
PRINTK("cpuId hwiActive taskLockCnt ");
|
||||
#endif
|
||||
#if (LOSCFG_TRACE_FRAME_EVENT_COUNT == 1)
|
||||
PRINTK("eventCount ");
|
||||
#endif
|
||||
if (LOSCFG_TRACE_FRAME_MAX_PARAMS > 0) {
|
||||
PRINTK("params ");
|
||||
}
|
||||
PRINTK("\n");
|
||||
}
|
||||
|
||||
STATIC VOID OsTraceInfoEventData(VOID)
|
||||
{
|
||||
UINT32 i, j;
|
||||
TraceEventFrame *frame = &g_traceRecoder.ctrl.frameBuf[0];
|
||||
|
||||
for (i = 0; i < g_traceRecoder.ctrl.maxRecordCount; i++, frame++) {
|
||||
PRINTK("%-7u 0x%-15llx 0x%-12x 0x%-7x 0x%-11x ", i, (UINT32)frame->curTime, frame->eventType,
|
||||
frame->curTask, frame->identity);
|
||||
#if (LOSCFG_TRACE_FRAME_CORE_MSG == 1)
|
||||
UINT32 taskLockCnt = frame->core.taskLockCnt;
|
||||
#if (LOSCFG_KERNEL_SMP == 1)
|
||||
/*
|
||||
* For smp systems, TRACE_LOCK will requst taskLock, and this counter
|
||||
* will increase by 1 in that case.
|
||||
*/
|
||||
taskLockCnt -= 1;
|
||||
#endif
|
||||
PRINTK("%-11u %-11u %-11u", frame->core.cpuId, frame->core.hwiActive, taskLockCnt);
|
||||
#endif
|
||||
#if (LOSCFG_TRACE_FRAME_EVENT_COUNT == 1)
|
||||
PRINTK("%-11u", frame->eventCount);
|
||||
#endif
|
||||
for (j = 0; j < LOSCFG_TRACE_FRAME_MAX_PARAMS; j++) {
|
||||
PRINTK("0x%-11x", frame->params[j]);
|
||||
}
|
||||
PRINTK("\n");
|
||||
}
|
||||
}
|
||||
|
||||
STATIC VOID OsTraceInfoDisplay(VOID)
|
||||
{
|
||||
OfflineHead *head = g_traceRecoder.head;
|
||||
|
||||
PRINTK("*******TraceInfo begin*******\n");
|
||||
PRINTK("clockFreq = %u\n", head->baseInfo.clockFreq);
|
||||
|
||||
OsTraceInfoObj();
|
||||
|
||||
OsTraceInfoEventTitle();
|
||||
OsTraceInfoEventData();
|
||||
|
||||
PRINTK("*******TraceInfo end*******\n");
|
||||
}
|
||||
|
||||
#if (LOSCFG_TRACE_CLIENT_INTERACT == 1)
|
||||
STATIC VOID OsTraceSendInfo(VOID)
|
||||
{
|
||||
UINT32 i;
|
||||
ObjData *obj = NULL;
|
||||
TraceEventFrame *frame = NULL;
|
||||
|
||||
OsTraceDataSend(HEAD, sizeof(OfflineHead), (UINT8 *)g_traceRecoder.head);
|
||||
|
||||
obj = &g_traceRecoder.ctrl.objBuf[0];
|
||||
for (i = 0; i < g_traceRecoder.ctrl.maxObjCount; i++) {
|
||||
OsTraceDataSend(OBJ, sizeof(ObjData), (UINT8 *)(obj + i));
|
||||
}
|
||||
|
||||
frame = &g_traceRecoder.ctrl.frameBuf[0];
|
||||
for (i = 0; i < g_traceRecoder.ctrl.maxRecordCount; i++) {
|
||||
OsTraceDataSend(EVENT, sizeof(TraceEventFrame), (UINT8 *)(frame + i));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
VOID OsTraceRecordDump(BOOL toClient)
|
||||
{
|
||||
if (!toClient) {
|
||||
OsTraceInfoDisplay();
|
||||
return;
|
||||
}
|
||||
|
||||
#if (LOSCFG_TRACE_CLIENT_INTERACT == 1)
|
||||
OsTraceSendInfo();
|
||||
#endif
|
||||
}
|
||||
|
||||
OfflineHead *OsTraceRecordGet(VOID)
|
||||
{
|
||||
return g_traceRecoder.head;
|
||||
}
|
||||
|
||||
#endif /* LOSCFG_RECORDER_MODE_OFFLINE == 1 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
113
components/trace/trace_online.c
Normal file
113
components/trace/trace_online.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_trace_pri.h"
|
||||
#include "trace_pipeline.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if (LOSCFG_RECORDER_MODE_ONLINE == 1)
|
||||
UINT32 OsTraceGetMaskTid(UINT32 taskId)
|
||||
{
|
||||
return taskId;
|
||||
}
|
||||
|
||||
VOID OsTraceSendHead(VOID)
|
||||
{
|
||||
TraceBaseHeaderInfo head = {
|
||||
.bigLittleEndian = TRACE_BIGLITTLE_WORD,
|
||||
.version = TRACE_VERSION(TRACE_MODE_ONLINE),
|
||||
.clockFreq = OS_SYS_CLOCK,
|
||||
};
|
||||
|
||||
OsTraceDataSend(HEAD, sizeof(TraceBaseHeaderInfo), (UINT8 *)&head);
|
||||
}
|
||||
|
||||
VOID OsTraceSendNotify(UINT32 type, UINT32 value)
|
||||
{
|
||||
TraceNotifyFrame frame = {
|
||||
.cmd = type,
|
||||
.param = value,
|
||||
};
|
||||
|
||||
OsTraceDataSend(NOTIFY, sizeof(TraceNotifyFrame), (UINT8 *)&frame);
|
||||
}
|
||||
|
||||
STATIC VOID OsTraceSendObj(const LosTaskCB *tcb)
|
||||
{
|
||||
ObjData obj;
|
||||
|
||||
OsTraceSetObj(&obj, tcb);
|
||||
OsTraceDataSend(OBJ, sizeof(ObjData), (UINT8 *)&obj);
|
||||
}
|
||||
|
||||
VOID OsTraceSendObjTable(VOID)
|
||||
{
|
||||
UINT32 loop;
|
||||
LosTaskCB *tcb = NULL;
|
||||
|
||||
for (loop = 0; loop < g_taskMaxNum; ++loop) {
|
||||
tcb = g_taskCBArray + loop;
|
||||
if (tcb->taskStatus & OS_TASK_STATUS_UNUSED) {
|
||||
continue;
|
||||
}
|
||||
OsTraceSendObj(tcb);
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsTraceObjAdd(UINT32 eventType, UINT32 taskId)
|
||||
{
|
||||
if (OsTraceIsEnable()) {
|
||||
OsTraceSendObj(OS_TCB_FROM_TID(taskId));
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsTraceWriteOrSendEvent(const TraceEventFrame *frame)
|
||||
{
|
||||
OsTraceDataSend(EVENT, sizeof(TraceEventFrame), (UINT8 *)frame);
|
||||
}
|
||||
|
||||
OfflineHead *OsTraceRecordGet(VOID)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* LOSCFG_RECORDER_MODE_ONLINE == 1 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
47
config.gni
Executable file
47
config.gni
Executable file
@@ -0,0 +1,47 @@
|
||||
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
# of conditions and the following disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
# to endorse or promote products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
declare_args() {
|
||||
enable_ohos_kernel_liteos_m_cppsupport = true
|
||||
enable_ohos_kernel_liteos_m_cpup = true
|
||||
enable_ohos_kernel_liteos_m_exchook = true
|
||||
enable_ohos_kernel_liteos_m_kal = true
|
||||
enable_ohos_kernel_liteos_m_fs = true
|
||||
enable_ohos_kernel_liteos_m_shell = true
|
||||
enable_ohos_kernel_liteos_m_backtrace = true
|
||||
enable_ohos_kernel_liteos_m_test = false
|
||||
enable_ohos_kernel_liteos_m_pm = true
|
||||
enable_ohos_kernel_liteos_m_trace = false
|
||||
enable_ohos_kernel_liteos_m_lwip = false
|
||||
enable_ohos_kernel_liteos_m_dynlink = false
|
||||
enable_ohos_kernel_liteos_m_tz = false
|
||||
ohos_kernel_liteos_m_lwip_path = "components/net/lwip-2.1:lwip"
|
||||
}
|
||||
|
||||
LITEOSTOPDIR = "//kernel/liteos_m"
|
||||
@@ -37,11 +37,11 @@ declare_args() {
|
||||
lite_component("kal") {
|
||||
features = []
|
||||
|
||||
if (enable_ohos_kernel_liteos_m_cmsis == true) {
|
||||
if (enable_ohos_kernel_liteos_m_cmsis) {
|
||||
features += [ "cmsis" ]
|
||||
}
|
||||
|
||||
if (enable_ohos_kernel_liteos_m_posix == true) {
|
||||
if (enable_ohos_kernel_liteos_m_posix) {
|
||||
features += [ "posix" ]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,17 +27,13 @@
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import("//kernel/liteos_m/config.gni")
|
||||
|
||||
static_library("cmsis") {
|
||||
sources = [ "cmsis_liteos2.c" ]
|
||||
|
||||
include_dirs = [
|
||||
"//third_party/bounds_checking_function/include",
|
||||
"../../kernel/include",
|
||||
"../../kernel/arch/include",
|
||||
"../../utils",
|
||||
]
|
||||
|
||||
public_configs = [ ":include" ]
|
||||
configs += [ "$LITEOSTOPDIR:los_config" ]
|
||||
}
|
||||
|
||||
config("include") {
|
||||
|
||||
@@ -112,7 +112,7 @@ osStatus_t osKernelGetInfo(osVersion_t *version, char *id_buf, uint32_t id_size)
|
||||
}
|
||||
uwRet = memcpy_s(id_buf, id_size, KERNEL_ID, id_size);
|
||||
if (uwRet != EOK) {
|
||||
PRINT_ERR("%s[%d] memcpy failed, error type = %u\n", __FUNCTION__, __LINE__, uwRet);
|
||||
PRINT_ERR("%s[%d] memcpy failed, error type = %lu\n", __FUNCTION__, __LINE__, uwRet);
|
||||
return osError;
|
||||
}
|
||||
}
|
||||
@@ -258,7 +258,7 @@ uint32_t osKernelGetTickFreq(void)
|
||||
|
||||
uint32_t osKernelGetSysTimerCount(void)
|
||||
{
|
||||
uint32_t countLow = 0;
|
||||
uint32_t countLow;
|
||||
if (OS_INT_ACTIVE) {
|
||||
countLow = 0U;
|
||||
} else {
|
||||
@@ -299,7 +299,9 @@ osThreadId_t osThreadNew(osThreadFunc_t func, void *argument, const osThreadAttr
|
||||
stTskInitParam.uwStackSize = attr ? attr->stack_size : LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
|
||||
stTskInitParam.pcName = (CHAR *)(attr ? attr->name : "[NULL]");
|
||||
stTskInitParam.usTaskPrio = usPriority;
|
||||
|
||||
if (attr->attr_bits == osThreadJoinable) {
|
||||
stTskInitParam.uwResved = LOS_TASK_ATTR_JOINABLE;
|
||||
}
|
||||
uwRet = LOS_TaskCreate(&uwTid, &stTskInitParam);
|
||||
|
||||
if (LOS_OK != uwRet) {
|
||||
@@ -576,6 +578,46 @@ osStatus_t osThreadResume(osThreadId_t thread_id)
|
||||
}
|
||||
|
||||
|
||||
osStatus_t osThreadDetach(osThreadId_t thread_id)
|
||||
{
|
||||
UINT32 ret;
|
||||
LosTaskCB *taskCB = (LosTaskCB *)thread_id;
|
||||
|
||||
if (thread_id == NULL) {
|
||||
return osErrorParameter;
|
||||
}
|
||||
|
||||
ret = LOS_TaskDetach(taskCB->taskID);
|
||||
if (ret == LOS_ERRNO_TSK_NOT_ALLOW_IN_INT) {
|
||||
return osErrorISR;
|
||||
} else if (ret != LOS_OK) {
|
||||
return osErrorResource;
|
||||
}
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
|
||||
osStatus_t osThreadJoin(osThreadId_t thread_id)
|
||||
{
|
||||
UINT32 ret;
|
||||
LosTaskCB *taskCB = (LosTaskCB *)thread_id;
|
||||
|
||||
if (thread_id == NULL) {
|
||||
return osErrorParameter;
|
||||
}
|
||||
|
||||
ret = LOS_TaskJoin(taskCB->taskID, NULL);
|
||||
if (ret == LOS_ERRNO_TSK_NOT_ALLOW_IN_INT) {
|
||||
return osErrorISR;
|
||||
} else if (ret != LOS_OK) {
|
||||
return osErrorResource;
|
||||
}
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
|
||||
osStatus_t osThreadTerminate(osThreadId_t thread_id)
|
||||
{
|
||||
UINT32 uwRet;
|
||||
@@ -1087,8 +1129,9 @@ osStatus_t osMutexDelete(osMutexId_t mutex_id)
|
||||
|
||||
osSemaphoreId_t osSemaphoreNew(uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr)
|
||||
{
|
||||
UINT32 uwRet;
|
||||
UINT32 uwRet = LOS_NOK;
|
||||
UINT32 uwSemId;
|
||||
UINT32 intSave;
|
||||
|
||||
UNUSED(attr);
|
||||
|
||||
@@ -1096,14 +1139,16 @@ osSemaphoreId_t osSemaphoreNew(uint32_t max_count, uint32_t initial_count, const
|
||||
return (osSemaphoreId_t)NULL;
|
||||
}
|
||||
|
||||
if (1 == max_count) {
|
||||
uwRet = LOS_BinarySemCreate((UINT16)initial_count, &uwSemId);
|
||||
} else {
|
||||
if (max_count > 0 && max_count <= OS_SEM_COUNTING_MAX_COUNT) {
|
||||
uwRet = LOS_SemCreate((UINT16)initial_count, &uwSemId);
|
||||
}
|
||||
|
||||
if (uwRet == LOS_OK) {
|
||||
return (osSemaphoreId_t)(GET_SEM(uwSemId));
|
||||
osSemaphoreId_t semaphore_id = (osSemaphoreId_t)(GET_SEM(uwSemId));
|
||||
intSave = LOS_IntLock();
|
||||
((LosSemCB *)semaphore_id)->maxSemCount = max_count;
|
||||
LOS_IntRestore(intSave);
|
||||
return semaphore_id;
|
||||
} else {
|
||||
return (osSemaphoreId_t)NULL;
|
||||
}
|
||||
@@ -1649,3 +1694,120 @@ const char *osMemoryPoolGetName(osMemoryPoolId_t mp_id)
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
// ==== Thread Flags Functions ====
|
||||
uint32_t osThreadFlagsSet(osThreadId_t thread_id, uint32_t flags)
|
||||
{
|
||||
UINT32 ret;
|
||||
LosTaskCB *taskCB = (LosTaskCB *)thread_id;
|
||||
EVENT_CB_S *eventCB = NULL;
|
||||
UINT32 curFlags;
|
||||
|
||||
if (taskCB == NULL) {
|
||||
return (uint32_t)osFlagsErrorParameter;
|
||||
}
|
||||
|
||||
eventCB = &(taskCB->event);
|
||||
curFlags = eventCB->uwEventID | flags;
|
||||
|
||||
ret = LOS_EventWrite(eventCB, (UINT32)flags);
|
||||
if (ret == LOS_ERRNO_EVENT_SETBIT_INVALID) {
|
||||
return (uint32_t)osFlagsErrorParameter;
|
||||
}
|
||||
|
||||
if (ret != LOS_OK) {
|
||||
return (uint32_t)osFlagsErrorResource;
|
||||
}
|
||||
|
||||
if (curFlags & taskCB->eventMask) {
|
||||
return curFlags & (~taskCB->eventMask);
|
||||
}
|
||||
|
||||
return curFlags;
|
||||
}
|
||||
|
||||
uint32_t osThreadFlagsClear(uint32_t flags)
|
||||
{
|
||||
UINT32 ret;
|
||||
UINT32 saveFlags;
|
||||
LosTaskCB *runTask = NULL;
|
||||
EVENT_CB_S *eventCB = NULL;
|
||||
|
||||
if (OS_INT_ACTIVE) {
|
||||
return (uint32_t)osFlagsErrorUnknown;
|
||||
}
|
||||
|
||||
runTask = g_losTask.runTask;
|
||||
eventCB = &(runTask->event);
|
||||
saveFlags = eventCB->uwEventID;
|
||||
|
||||
ret = LOS_EventClear(eventCB, ~(UINT32)flags);
|
||||
if (ret == LOS_OK) {
|
||||
return (uint32_t)saveFlags;
|
||||
}
|
||||
|
||||
return (uint32_t)osFlagsErrorResource;
|
||||
}
|
||||
|
||||
uint32_t osThreadFlagsGet(void)
|
||||
{
|
||||
LosTaskCB *runTask = NULL;
|
||||
EVENT_CB_S *eventCB = NULL;
|
||||
|
||||
if (OS_INT_ACTIVE) {
|
||||
return (uint32_t)osFlagsErrorUnknown;
|
||||
}
|
||||
|
||||
runTask = g_losTask.runTask;
|
||||
eventCB = &(runTask->event);
|
||||
|
||||
return (uint32_t)(eventCB->uwEventID);
|
||||
}
|
||||
|
||||
uint32_t osThreadFlagsWait(uint32_t flags, uint32_t options, uint32_t timeout)
|
||||
{
|
||||
UINT32 ret;
|
||||
UINT32 mode = 0;
|
||||
LosTaskCB *runTask = NULL;
|
||||
EVENT_CB_S *eventCB = NULL;
|
||||
|
||||
if (OS_INT_ACTIVE) {
|
||||
return (uint32_t)osFlagsErrorUnknown;
|
||||
}
|
||||
|
||||
if (options > (osFlagsWaitAny | osFlagsWaitAll | osFlagsNoClear)) {
|
||||
return (uint32_t)osFlagsErrorParameter;
|
||||
}
|
||||
|
||||
if ((options & osFlagsWaitAll) == osFlagsWaitAll) {
|
||||
mode |= LOS_WAITMODE_AND;
|
||||
} else {
|
||||
mode |= LOS_WAITMODE_OR;
|
||||
}
|
||||
|
||||
if ((options & osFlagsNoClear) == osFlagsNoClear) {
|
||||
mode &= ~LOS_WAITMODE_CLR;
|
||||
} else {
|
||||
mode |= LOS_WAITMODE_CLR;
|
||||
}
|
||||
|
||||
runTask = g_losTask.runTask;
|
||||
eventCB = &(runTask->event);
|
||||
|
||||
ret = LOS_EventRead(eventCB, (UINT32)flags, mode, (UINT32)timeout);
|
||||
if (!(ret & LOS_ERRTYPE_ERROR)) {
|
||||
return (uint32_t)eventCB->uwEventID | ret;
|
||||
}
|
||||
|
||||
switch (ret) {
|
||||
case LOS_ERRNO_EVENT_PTR_NULL:
|
||||
case LOS_ERRNO_EVENT_SETBIT_INVALID:
|
||||
case LOS_ERRNO_EVENT_EVENTMASK_INVALID:
|
||||
case LOS_ERRNO_EVENT_FLAGS_INVALID:
|
||||
return (uint32_t)osFlagsErrorParameter;
|
||||
case LOS_ERRNO_EVENT_READ_TIMEOUT:
|
||||
return (uint32_t)osFlagsErrorTimeout;
|
||||
default:
|
||||
return (uint32_t)osFlagsErrorResource;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,10 +50,10 @@ extern "C" {
|
||||
* @version 1.0
|
||||
*/
|
||||
typedef enum {
|
||||
/** The timer is not allowed to wake up the RTOS. */
|
||||
osTimerRousesIgnore = 0,
|
||||
/** The timer is allowed to wake up the RTOS. */
|
||||
osTimerRousesAllow = 1
|
||||
/** The timer is not allowed to wake up the RTOS. */
|
||||
osTimerRousesIgnore = 0,
|
||||
/** The timer is allowed to wake up the RTOS. */
|
||||
osTimerRousesAllow = 1
|
||||
} osTimerRouses_t;
|
||||
|
||||
/**
|
||||
@@ -61,10 +61,10 @@ typedef enum {
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
/** The timer ignores alignment. */
|
||||
osTimerAlignIgnore = 0,
|
||||
/** The timer allows alignment. */
|
||||
osTimerAlignAllow = 1
|
||||
/** The timer ignores alignment. */
|
||||
osTimerAlignIgnore = 0,
|
||||
/** The timer allows alignment. */
|
||||
osTimerAlignAllow = 1
|
||||
} osTimerAlign_t;
|
||||
|
||||
osTimerId_t osTimerExtNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr,
|
||||
|
||||
@@ -27,34 +27,28 @@
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import("//kernel/liteos_m/config.gni")
|
||||
|
||||
config("include") {
|
||||
include_dirs = [ "include" ]
|
||||
}
|
||||
|
||||
static_library("posix") {
|
||||
sources = [
|
||||
"src/errno.c",
|
||||
"src/libc.c",
|
||||
"src/malloc.c",
|
||||
"src/mqueue.c",
|
||||
"src/pthread.c",
|
||||
"src/pthread_attr.c",
|
||||
"src/pthread_cond.c",
|
||||
"src/pthread_mutex.c",
|
||||
"src/semaphore.c",
|
||||
"src/time.c",
|
||||
"//third_party/musl/src/string/strdup.c",
|
||||
]
|
||||
|
||||
include_dirs = [
|
||||
"include",
|
||||
"../../kernel/arch/include",
|
||||
"../../kernel/include",
|
||||
"../../utils",
|
||||
]
|
||||
|
||||
public_configs = [ ":include" ]
|
||||
}
|
||||
configs += [ "$LITEOSTOPDIR:los_config" ]
|
||||
|
||||
config("include") {
|
||||
include_dirs = [
|
||||
"include",
|
||||
"//third_party/musl/porting/liteos_m/kernel/include",
|
||||
"//third_party/bounds_checking_function/include",
|
||||
]
|
||||
public_deps = [ "//third_party/musl/porting/liteos_m/kernel" ]
|
||||
}
|
||||
|
||||
@@ -34,56 +34,65 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <securec.h>
|
||||
#include <limits.h>
|
||||
#include "los_config.h"
|
||||
#include "los_task.h"
|
||||
|
||||
#define PTHREAD_DEFAULT_NAME "pthread"
|
||||
#define PTHREAD_DEFAULT_NAME_LEN 8
|
||||
#define PTHREAD_NAMELEN 16
|
||||
|
||||
typedef struct {
|
||||
void *(*startRoutine)(void *);
|
||||
void *param;
|
||||
char name[PTHREAD_NAMELEN];
|
||||
}PthreadData;
|
||||
} PthreadData;
|
||||
|
||||
static void *PthreadEntry(UINT32 param)
|
||||
{
|
||||
PthreadData *pthreadData = (PthreadData *)(UINTPTR)param;
|
||||
void *(*startRoutine)(void *) = pthreadData->startRoutine;
|
||||
void *ret = startRoutine(pthreadData->param);
|
||||
free(pthreadData);
|
||||
pthread_exit(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int IsPthread(pthread_t thread)
|
||||
{
|
||||
return ((UINT32)thread <= LOSCFG_BASE_CORE_TSK_LIMIT) &&
|
||||
(OS_TCB_FROM_TID((UINT32)thread)->taskEntry == PthreadEntry);
|
||||
return ((UINT32)thread <= LOSCFG_BASE_CORE_TSK_LIMIT);
|
||||
}
|
||||
|
||||
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
void *(*startRoutine)(void *), void *arg)
|
||||
static int PthreadCreateAttrInit(const pthread_attr_t *attr, void *(*startRoutine)(void *), void *arg,
|
||||
TSK_INIT_PARAM_S *taskInitParam)
|
||||
{
|
||||
TSK_INIT_PARAM_S taskInitParam = {0};
|
||||
const pthread_attr_t *threadAttr = attr;
|
||||
struct sched_param schedParam = { 0 };
|
||||
PthreadData *pthreadData = NULL;
|
||||
UINT32 taskID;
|
||||
|
||||
if ((thread == NULL) || (startRoutine == NULL)) {
|
||||
return EINVAL;
|
||||
INT32 policy = 0;
|
||||
pthread_attr_t attrTmp;
|
||||
INT32 ret;
|
||||
errno_t error;
|
||||
|
||||
if (!attr) {
|
||||
(VOID)pthread_attr_init(&attrTmp);
|
||||
threadAttr = &attrTmp;
|
||||
}
|
||||
|
||||
taskInitParam.usTaskPrio = LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO;
|
||||
taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
|
||||
if (attr) {
|
||||
if (attr->detachstate == PTHREAD_CREATE_DETACHED) {
|
||||
return ENOTSUP;
|
||||
if (threadAttr->stackaddr_set != 0) {
|
||||
return ENOTSUP;
|
||||
}
|
||||
if (threadAttr->stacksize < PTHREAD_STACK_MIN) {
|
||||
return EINVAL;
|
||||
}
|
||||
taskInitParam->uwStackSize = threadAttr->stacksize;
|
||||
if (threadAttr->inheritsched == PTHREAD_EXPLICIT_SCHED) {
|
||||
taskInitParam->usTaskPrio = (UINT16)threadAttr->schedparam.sched_priority;
|
||||
} else {
|
||||
ret = pthread_getschedparam(pthread_self(), &policy, &schedParam);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
if (attr->stackaddr_set) {
|
||||
return ENOTSUP;
|
||||
}
|
||||
if (attr->stacksize_set) {
|
||||
taskInitParam.uwStackSize = attr->stacksize;
|
||||
}
|
||||
taskInitParam.usTaskPrio = (UINT16)attr->schedparam.sched_priority;
|
||||
taskInitParam->usTaskPrio = (UINT16)schedParam.sched_priority;
|
||||
}
|
||||
|
||||
pthreadData = (PthreadData *)malloc(sizeof(PthreadData));
|
||||
@@ -91,19 +100,42 @@ int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
pthreadData->startRoutine = startRoutine;
|
||||
pthreadData->param = arg;
|
||||
taskInitParam.pcName = pthreadData->name;
|
||||
taskInitParam.pfnTaskEntry = PthreadEntry;
|
||||
taskInitParam.uwArg = (UINT32)(UINTPTR)pthreadData;
|
||||
|
||||
if (LOS_TaskCreateOnly(&taskID, &taskInitParam) != LOS_OK) {
|
||||
error = memcpy_s(pthreadData->name, PTHREAD_NAMELEN, PTHREAD_DEFAULT_NAME, PTHREAD_DEFAULT_NAME_LEN);
|
||||
if (error != EOK) {
|
||||
free(pthreadData);
|
||||
return error;
|
||||
}
|
||||
pthreadData->startRoutine = startRoutine;
|
||||
pthreadData->param = arg;
|
||||
taskInitParam->pcName = pthreadData->name;
|
||||
taskInitParam->pfnTaskEntry = PthreadEntry;
|
||||
taskInitParam->uwArg = (UINT32)(UINTPTR)pthreadData;
|
||||
if (threadAttr->detachstate != PTHREAD_CREATE_DETACHED) {
|
||||
taskInitParam->uwResved = LOS_TASK_ATTR_JOINABLE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
void *(*startRoutine)(void *), void *arg)
|
||||
{
|
||||
TSK_INIT_PARAM_S taskInitParam = { 0 };
|
||||
UINT32 taskID;
|
||||
UINT32 ret;
|
||||
|
||||
if ((thread == NULL) || (startRoutine == NULL)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* set pthread default name */
|
||||
(void)sprintf_s(taskInitParam.pcName, PTHREAD_NAMELEN, "pthread%u", taskID);
|
||||
ret = PthreadCreateAttrInit(attr, startRoutine, arg, &taskInitParam);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (LOS_TaskCreateOnly(&taskID, &taskInitParam) != LOS_OK) {
|
||||
free((VOID *)(UINTPTR)taskInitParam.uwArg);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
(void)LOS_TaskResume(taskID);
|
||||
|
||||
@@ -164,55 +196,74 @@ int pthread_cancel(pthread_t thread)
|
||||
|
||||
int pthread_join(pthread_t thread, void **retval)
|
||||
{
|
||||
UINT32 taskStatus;
|
||||
|
||||
if (!IsPthread(thread)) {
|
||||
UINTPTR result;
|
||||
UINT32 ret = LOS_TaskJoin((UINT32)thread, &result);
|
||||
if (ret == LOS_ERRNO_TSK_NOT_JOIN_SELF) {
|
||||
return EDEADLK;
|
||||
} else if (ret != LOS_OK) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (retval) {
|
||||
/* retrieve thread exit code is not supported currently */
|
||||
return ENOTSUP;
|
||||
if (retval != NULL) {
|
||||
*retval = (VOID *)result;
|
||||
}
|
||||
|
||||
if (thread == pthread_self()) {
|
||||
return EDEADLK;
|
||||
}
|
||||
|
||||
while (LOS_TaskStatusGet((UINT32)thread, &taskStatus) == LOS_OK) {
|
||||
(void)LOS_TaskDelay(10); /* 10: Waiting for the end of thread execution. */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_detach(pthread_t thread)
|
||||
{
|
||||
if (!IsPthread(thread)) {
|
||||
UINT32 ret = LOS_TaskDetach((UINT32)thread);
|
||||
if (ret == LOS_ERRNO_TSK_NOT_JOIN) {
|
||||
return ESRCH;
|
||||
} else if (ret != LOS_OK) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
return ENOSYS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pthread_exit(void *retVal)
|
||||
{
|
||||
(void)retVal;
|
||||
UINT32 intSave;
|
||||
|
||||
LosTaskCB *tcb = OS_TCB_FROM_TID(LOS_CurTaskIDGet());
|
||||
free((PthreadData *)(UINTPTR)tcb->arg);
|
||||
(void)LOS_TaskDelete(LOS_CurTaskIDGet());
|
||||
tcb->joinRetval = (UINTPTR)retVal;
|
||||
PthreadData *pthreadData = (PthreadData *)(UINTPTR)tcb->arg;
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
tcb->taskName = PTHREAD_DEFAULT_NAME;
|
||||
LOS_IntRestore(intSave);
|
||||
free(pthreadData);
|
||||
(void)LOS_TaskDelete(tcb->taskID);
|
||||
}
|
||||
|
||||
int pthread_setname_np(pthread_t thread, const char *name)
|
||||
{
|
||||
UINT32 intSave;
|
||||
LosTaskCB *taskCB = NULL;
|
||||
char *taskName = LOS_TaskNameGet((UINT32)thread);
|
||||
if (taskName == NULL || !IsPthread(thread)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (strnlen(name, PTHREAD_NAMELEN) >= PTHREAD_NAMELEN) {
|
||||
return ERANGE;
|
||||
}
|
||||
(void)strcpy_s(taskName, PTHREAD_NAMELEN, name);
|
||||
|
||||
taskCB = OS_TCB_FROM_TID((UINT32)thread);
|
||||
intSave = LOS_IntLock();
|
||||
if (taskCB->taskStatus & OS_TASK_STATUS_EXIT) {
|
||||
LOS_IntRestore(intSave);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (taskCB->taskEntry == PthreadEntry) {
|
||||
(void)strcpy_s(taskName, PTHREAD_NAMELEN, name);
|
||||
} else {
|
||||
LOS_IntRestore(intSave);
|
||||
return EINVAL;
|
||||
}
|
||||
LOS_IntRestore(intSave);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -231,3 +231,23 @@ int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stackSize)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sched_get_priority_min(int policy)
|
||||
{
|
||||
if (policy != SCHED_RR) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return LOS_TASK_PRIORITY_LOWEST;
|
||||
}
|
||||
|
||||
int sched_get_priority_max(int policy)
|
||||
{
|
||||
if (policy != SCHED_RR) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return LOS_TASK_PRIORITY_HIGHEST;
|
||||
}
|
||||
|
||||
@@ -202,18 +202,22 @@ STATIC INT32 ProcessReturnVal(pthread_cond_t *cond, INT32 val)
|
||||
}
|
||||
|
||||
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
const struct timespec *absTime)
|
||||
const struct timespec *ts)
|
||||
{
|
||||
UINT32 absTicks;
|
||||
INT32 ret;
|
||||
UINT64 absTicks;
|
||||
const UINT32 nsPerTick = OS_SYS_NS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND;
|
||||
struct timespec tp;
|
||||
UINT64 nseconds;
|
||||
UINT64 currTime;
|
||||
|
||||
if ((cond == NULL) || (mutex == NULL) || (absTime == NULL)) {
|
||||
if ((cond == NULL) || (mutex == NULL) || (ts == NULL)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (CondInitCheck(cond)) {
|
||||
ret = pthread_cond_init(cond, NULL);
|
||||
if (ret != ENOERR) {
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -222,22 +226,29 @@ int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
cond->count++;
|
||||
(VOID)pthread_mutex_unlock(cond->mutex);
|
||||
|
||||
if ((absTime->tv_sec == 0) && (absTime->tv_nsec == 0)) {
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
|
||||
if (!ValidTimeSpec(absTime)) {
|
||||
if (!ValidTimeSpec(ts)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
absTicks = OsTimeSpec2Tick(absTime);
|
||||
if (pthread_mutex_unlock(mutex) != ENOERR) {
|
||||
clock_gettime(CLOCK_REALTIME, &tp);
|
||||
currTime = (UINT64)tp.tv_sec * OS_SYS_NS_PER_SECOND + tp.tv_nsec;
|
||||
nseconds = (UINT64)ts->tv_sec * OS_SYS_NS_PER_SECOND + ts->tv_nsec;
|
||||
if (currTime >= nseconds) {
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
absTicks = ((nseconds - currTime) + nsPerTick - 1) / nsPerTick + 1;
|
||||
if (absTicks >= UINT32_MAX) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (pthread_mutex_unlock(mutex) != 0) {
|
||||
PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
ret = (INT32)LOS_EventRead(&(cond->event), 0x0f, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, absTicks);
|
||||
(VOID)LOS_EventClear(&(cond->event), 0);
|
||||
ret = (INT32)LOS_EventRead(&(cond->event), 0x0f, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, (UINT32)absTicks);
|
||||
|
||||
if (pthread_mutex_lock(mutex) != ENOERR) {
|
||||
if (pthread_mutex_lock(mutex) != 0) {
|
||||
PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ int pthread_mutex_destroy(pthread_mutex_t *mutex)
|
||||
return MapError(ret);
|
||||
}
|
||||
mutex->handle = _MUX_INVALID_HANDLE;
|
||||
mutex->magic = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -186,3 +186,21 @@ int sem_timedwait(sem_t *sem, const struct timespec *timeout)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sem_getvalue(sem_t *sem, int *currVal)
|
||||
{
|
||||
UINT32 ret;
|
||||
|
||||
if ((sem == NULL) || (currVal == NULL)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = LOS_SemGetValue(sem->s_handle, currVal);
|
||||
if (ret) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "los_swtmr.h"
|
||||
#include "los_tick.h"
|
||||
#include "los_context.h"
|
||||
#include "los_interrupt.h"
|
||||
|
||||
/* accumulative time delta from discontinuous modify */
|
||||
STATIC struct timespec g_accDeltaFromSet;
|
||||
@@ -62,9 +63,6 @@ STATIC const UINT8 g_montbl[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30,
|
||||
*/
|
||||
long timezone = -8 * 60 * 60; // defaults to CST: 8 hours east of the Prime Meridian
|
||||
|
||||
/* internal shared struct tm object for localtime and gmtime */
|
||||
static struct tm g_tm;
|
||||
|
||||
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
|
||||
{
|
||||
UINT64 nseconds;
|
||||
@@ -507,7 +505,8 @@ struct tm *gmtime_r(const time_t *timep, struct tm *result)
|
||||
|
||||
struct tm *gmtime(const time_t *timer)
|
||||
{
|
||||
return gmtime_r(timer, &g_tm);
|
||||
static struct tm tm;
|
||||
return gmtime_r(timer, &tm);
|
||||
}
|
||||
|
||||
struct tm *localtime_r(const time_t *timep, struct tm *result)
|
||||
@@ -525,7 +524,8 @@ struct tm *localtime_r(const time_t *timep, struct tm *result)
|
||||
|
||||
struct tm *localtime(const time_t *timer)
|
||||
{
|
||||
return localtime_r(timer, &g_tm);
|
||||
static struct tm tm;
|
||||
return localtime_r(timer, &tm);
|
||||
}
|
||||
|
||||
static time_t ConvertUtc2Secs(struct tm *tm)
|
||||
|
||||
@@ -27,32 +27,34 @@
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import("//kernel/liteos_m/config.gni")
|
||||
|
||||
static_library("kernel") {
|
||||
sources = [
|
||||
"src/los_event.c",
|
||||
"src/los_init.c",
|
||||
"src/los_mux.c",
|
||||
"src/los_queue.c",
|
||||
"src/los_sched.c",
|
||||
"src/los_sem.c",
|
||||
"src/los_sortlink.c",
|
||||
"src/los_swtmr.c",
|
||||
"src/los_task.c",
|
||||
"src/los_tick.c",
|
||||
"src/los_sched.c",
|
||||
"src/los_sortlink.c",
|
||||
"src/mm/los_membox.c",
|
||||
"src/mm/los_memory.c",
|
||||
]
|
||||
|
||||
include_dirs = [
|
||||
"include",
|
||||
"arch/include",
|
||||
"../components/cpup",
|
||||
"../components/exchook",
|
||||
"../components/backtrace",
|
||||
"../utils",
|
||||
"//third_party/bounds_checking_function/include",
|
||||
"../components/power",
|
||||
"../components/dynlink",
|
||||
]
|
||||
|
||||
configs += [ "$LITEOSTOPDIR:los_config" ]
|
||||
|
||||
if ("$board_cpu" == "cortex-m3") {
|
||||
deps = [ "arch/arm/cortex-m3/gcc/:arch" ]
|
||||
} else if ("$board_cpu" == "cortex-m4") {
|
||||
@@ -60,7 +62,11 @@ static_library("kernel") {
|
||||
} else if ("$board_cpu" == "cortex-m7") {
|
||||
deps = [ "arch/arm/cortex-m7/gcc/:arch" ]
|
||||
} else if ("$board_cpu" == "cortex-m33") {
|
||||
deps = [ "arch/arm/cortex-m33/gcc/:arch" ]
|
||||
if (enable_ohos_kernel_liteos_m_tz) {
|
||||
deps = [ "arch/arm/cortex-m33/gcc/TZ:arch" ]
|
||||
} else {
|
||||
deps = [ "arch/arm/cortex-m33/gcc/NTZ:arch" ]
|
||||
}
|
||||
} else if ("$board_cpu" == "") {
|
||||
if ("$board_arch" == "rv32imac" || "$board_arch" == "rv32imafdc") {
|
||||
deps = [ "arch/risc-v/riscv32/gcc:arch" ]
|
||||
|
||||
43
kernel/arch/arm/arm9/gcc/BUILD.gn
Normal file
43
kernel/arch/arm/arm9/gcc/BUILD.gn
Normal file
@@ -0,0 +1,43 @@
|
||||
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
# of conditions and the following disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
# to endorse or promote products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import("//kernel/liteos_m/config.gni")
|
||||
|
||||
static_library("arch") {
|
||||
sources = [
|
||||
"los_context.c",
|
||||
"los_dispatch.S",
|
||||
"los_exc.S",
|
||||
"los_interrupt.c",
|
||||
"los_timer.c",
|
||||
"reset_vector.S",
|
||||
]
|
||||
|
||||
configs += [ "$LITEOSTOPDIR:los_config" ]
|
||||
}
|
||||
120
kernel/arch/arm/arm9/gcc/los_arch_atomic.h
Normal file
120
kernel/arch/arm/arm9/gcc/los_arch_atomic.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_ARCH_ATOMIC_H
|
||||
#define _LOS_ARCH_ATOMIC_H
|
||||
|
||||
#include "los_compiler.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* @ingroup los_arch_atomic
|
||||
* @brief Atomic exchange for 32-bit variable.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to implement the atomic exchange for 32-bit variable and return the previous value of the atomic variable.
|
||||
* @attention
|
||||
* <ul>The pointer v must not be NULL.</ul>
|
||||
*
|
||||
* @param v [IN] The variable pointer.
|
||||
* @param val [IN] The exchange value.
|
||||
*
|
||||
* @retval #INT32 The previous value of the atomic variable
|
||||
* @par Dependency:
|
||||
* <ul><li>los_arch_atomic.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see
|
||||
*/
|
||||
STATIC INLINE INT32 HalAtomicXchg32bits(volatile INT32 *v, INT32 val)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup los_arch_atomic
|
||||
* @brief Atomic auto-decrement.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to implement the atomic auto-decrement and return the result of auto-decrement.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>The pointer v must not be NULL.</li>
|
||||
* <li>The value which v point to must not be INT_MIN to avoid overflow after reducing 1.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param v [IN] The addSelf variable pointer.
|
||||
*
|
||||
* @retval #INT32 The return value of variable auto-decrement.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_arch_atomic.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see
|
||||
*/
|
||||
STATIC INLINE INT32 HalAtomicDecRet(volatile INT32 *v)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup los_arch_atomic
|
||||
* @brief Atomic exchange for 32-bit variable with compare.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to implement the atomic exchange for 32-bit variable, if the value of variable is equal to oldVal.
|
||||
* @attention
|
||||
* <ul>The pointer v must not be NULL.</ul>
|
||||
*
|
||||
* @param v [IN] The variable pointer.
|
||||
* @param val [IN] The new value.
|
||||
* @param oldVal [IN] The old value.
|
||||
*
|
||||
* @retval TRUE The previous value of the atomic variable is not equal to oldVal.
|
||||
* @retval FALSE The previous value of the atomic variable is equal to oldVal.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_arch_atomic.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see
|
||||
*/
|
||||
STATIC INLINE BOOL HalAtomicCmpXchg32bits(volatile INT32 *v, INT32 val, INT32 oldVal)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_ARCH_ATOMIC_H */
|
||||
|
||||
181
kernel/arch/arm/arm9/gcc/los_arch_context.h
Normal file
181
kernel/arch/arm/arm9/gcc/los_arch_context.h
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_ARCH_CONTEXT_H
|
||||
#define _LOS_ARCH_CONTEXT_H
|
||||
|
||||
#include "los_config.h"
|
||||
#include "los_compiler.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define PSR_T_ARM 0x00000000U
|
||||
#define PSR_T_THUMB 0x00000020U
|
||||
#define PSR_MODE_SVC 0x00000013U
|
||||
#define PSR_MODE_SYS 0x0000001FU
|
||||
|
||||
#define PSR_MODE_SVC_THUMB (PSR_MODE_SVC | PSR_T_THUMB)
|
||||
#define PSR_MODE_SVC_ARM (PSR_MODE_SVC | PSR_T_ARM)
|
||||
|
||||
#define PSR_MODE_SYS_THUMB (PSR_MODE_SYS | PSR_T_THUMB)
|
||||
#define PSR_MODE_SYS_ARM (PSR_MODE_SYS | PSR_T_ARM)
|
||||
|
||||
VOID OsTaskEntryArm(VOID);
|
||||
VOID OsTaskEntryThumb(VOID);
|
||||
|
||||
typedef struct TagTskContext {
|
||||
UINT32 spsr;
|
||||
UINT32 r0;
|
||||
UINT32 r1;
|
||||
UINT32 r2;
|
||||
UINT32 r3;
|
||||
UINT32 r4;
|
||||
UINT32 r5;
|
||||
UINT32 r6;
|
||||
UINT32 r7;
|
||||
UINT32 r8;
|
||||
UINT32 r9;
|
||||
UINT32 r10;
|
||||
UINT32 r11;
|
||||
UINT32 r12;
|
||||
UINT32 sp;
|
||||
UINT32 lr;
|
||||
UINT32 pc;
|
||||
} TaskContext;
|
||||
|
||||
/**
|
||||
* @ingroup los_config
|
||||
* @brief: Task start running function.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to start a task.
|
||||
*
|
||||
* @attention:
|
||||
* <ul><li>None.</li></ul>
|
||||
*
|
||||
* @param: None.
|
||||
*
|
||||
* @retval None.
|
||||
*
|
||||
* @par Dependency:
|
||||
* <ul><li>los_config.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see None.
|
||||
*/
|
||||
extern VOID HalStartToRun(VOID);
|
||||
|
||||
/**
|
||||
* @ingroup los_arch_context
|
||||
* @brief Wait for interrupt.
|
||||
*
|
||||
* @par Description:
|
||||
* <ul>
|
||||
* <li>This API is used to suspend execution until interrupt or a debug request occurs.</li>
|
||||
* </ul>
|
||||
* @attention None.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @retval: None.
|
||||
*
|
||||
* @par Dependency:
|
||||
* los_arch_context.h: the header file that contains the API declaration.
|
||||
* @see None.
|
||||
*/
|
||||
extern VOID wfi(VOID);
|
||||
|
||||
/**
|
||||
* @ingroup los_arch_context
|
||||
* @brief: mem fence function.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to fence for memory.
|
||||
*
|
||||
* @attention:
|
||||
* <ul><li>None.</li></ul>
|
||||
*
|
||||
* @param: None.
|
||||
*
|
||||
* @retval:None.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_arch_context.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see None.
|
||||
*/
|
||||
extern VOID dmb(VOID);
|
||||
|
||||
/**
|
||||
* @ingroup los_arch_context
|
||||
* @brief: mem fence function.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is same as dmb, it just for adaptation.
|
||||
*
|
||||
* @attention:
|
||||
* <ul><li>None.</li></ul>
|
||||
*
|
||||
* @param: None.
|
||||
*
|
||||
* @retval:None.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_arch_context.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see None.
|
||||
*/
|
||||
extern VOID dsb(VOID);
|
||||
|
||||
/**
|
||||
* @ingroup los_arch_context
|
||||
* @brief: instruction fence function.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to fence for instruction.
|
||||
*
|
||||
* @attention:
|
||||
* <ul><li>None.</li></ul>
|
||||
*
|
||||
* @param: None.
|
||||
*
|
||||
* @retval:None.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_arch_context.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see None.
|
||||
*/
|
||||
extern VOID isb(VOID);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_ARCH_CONTEXT_H */
|
||||
350
kernel/arch/arm/arm9/gcc/los_arch_interrupt.h
Normal file
350
kernel/arch/arm/arm9/gcc/los_arch_interrupt.h
Normal file
@@ -0,0 +1,350 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_ARCH_INTERRUPT_H
|
||||
#define _LOS_ARCH_INTERRUPT_H
|
||||
|
||||
#include "los_config.h"
|
||||
#include "los_compiler.h"
|
||||
#include "los_interrupt.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* *
|
||||
* @ingroup los_arch_interrupt
|
||||
* Maximum number of used hardware interrupts.
|
||||
*/
|
||||
#ifndef OS_HWI_MAX_NUM
|
||||
#define OS_HWI_MAX_NUM LOSCFG_PLATFORM_HWI_LIMIT
|
||||
#endif
|
||||
|
||||
/* *
|
||||
* @ingroup los_arch_interrupt
|
||||
* Highest priority of a hardware interrupt.
|
||||
*/
|
||||
#ifndef OS_HWI_PRIO_HIGHEST
|
||||
#define OS_HWI_PRIO_HIGHEST 0
|
||||
#endif
|
||||
|
||||
/* *
|
||||
* @ingroup los_arch_interrupt
|
||||
* Lowest priority of a hardware interrupt.
|
||||
*/
|
||||
#ifndef OS_HWI_PRIO_LOWEST
|
||||
#define OS_HWI_PRIO_LOWEST 7
|
||||
#endif
|
||||
|
||||
|
||||
/* *
|
||||
* @ingroup los_arch_interrupt
|
||||
* Define the type of a hardware interrupt vector table function.
|
||||
*/
|
||||
typedef VOID (**HWI_VECTOR_FUNC)(void);
|
||||
|
||||
/* *
|
||||
* @ingroup los_arch_interrupt
|
||||
* Count of interrupts.
|
||||
*/
|
||||
extern UINT32 g_intCount;
|
||||
|
||||
/* *
|
||||
* @ingroup los_arch_interrupt
|
||||
* Count of arm9 system interrupt vector.
|
||||
*/
|
||||
#define OS_SYS_VECTOR_CNT 0
|
||||
|
||||
/* *
|
||||
* @ingroup los_arch_interrupt
|
||||
* Count of arm9 interrupt vector.
|
||||
*/
|
||||
#define OS_VECTOR_CNT (OS_SYS_VECTOR_CNT + OS_HWI_MAX_NUM)
|
||||
|
||||
/* *
|
||||
* @ingroup los_arch_interrupt
|
||||
* Hardware interrupt error code: Invalid interrupt number.
|
||||
*
|
||||
* Value: 0x02000900
|
||||
*
|
||||
* Solution: Ensure that the interrupt number is valid. The value range of the interrupt number applicable for a Cortex-A7 platform is [OS_USER_HWI_MIN,OS_USER_HWI_MAX].
|
||||
*/
|
||||
#define OS_ERRNO_HWI_NUM_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x00)
|
||||
|
||||
/* *
|
||||
* @ingroup los_arch_interrupt
|
||||
* Hardware interrupt error code: Null hardware interrupt handling function.
|
||||
*
|
||||
* Value: 0x02000901
|
||||
*
|
||||
* Solution: Pass in a valid non-null hardware interrupt handling function.
|
||||
*/
|
||||
#define OS_ERRNO_HWI_PROC_FUNC_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x01)
|
||||
|
||||
/* *
|
||||
* @ingroup los_arch_interrupt
|
||||
* Hardware interrupt error code: Insufficient interrupt resources for hardware interrupt creation.
|
||||
*
|
||||
* Value: 0x02000902
|
||||
*
|
||||
* Solution: Increase the configured maximum number of supported hardware interrupts.
|
||||
*/
|
||||
#define OS_ERRNO_HWI_CB_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x02)
|
||||
|
||||
/* *
|
||||
* @ingroup los_arch_interrupt
|
||||
* Hardware interrupt error code: Insufficient memory for hardware interrupt initialization.
|
||||
*
|
||||
* Value: 0x02000903
|
||||
*
|
||||
* Solution: Expand the configured memory.
|
||||
*/
|
||||
#define OS_ERRNO_HWI_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x03)
|
||||
|
||||
/* *
|
||||
* @ingroup los_arch_interrupt
|
||||
* Hardware interrupt error code: The interrupt has already been created.
|
||||
*
|
||||
* Value: 0x02000904
|
||||
*
|
||||
* Solution: Check whether the interrupt specified by the passed-in interrupt number has already been created.
|
||||
*/
|
||||
#define OS_ERRNO_HWI_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x04)
|
||||
|
||||
/* *
|
||||
* @ingroup los_arch_interrupt
|
||||
* Hardware interrupt error code: Invalid interrupt priority.
|
||||
*
|
||||
* Value: 0x02000905
|
||||
*
|
||||
* Solution: Ensure that the interrupt priority is valid. The value range of the interrupt priority applicable for a Cortex-A7 platform is [0,15].
|
||||
*/
|
||||
#define OS_ERRNO_HWI_PRIO_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x05)
|
||||
|
||||
/* *
|
||||
* @ingroup los_arch_interrupt
|
||||
* Hardware interrupt error code: Incorrect interrupt creation mode.
|
||||
*
|
||||
* Value: 0x02000906
|
||||
*
|
||||
* Solution: The interrupt creation mode can be only set to OS_HWI_MODE_COMM or OS_HWI_MODE_FAST of which the value can be 0 or 1.
|
||||
*/
|
||||
#define OS_ERRNO_HWI_MODE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x06)
|
||||
|
||||
/* *
|
||||
* @ingroup los_arch_interrupt
|
||||
* Hardware interrupt error code: The interrupt has already been created as a fast interrupt.
|
||||
*
|
||||
* Value: 0x02000907
|
||||
*
|
||||
* Solution: Check whether the interrupt specified by the passed-in interrupt number has already been created.
|
||||
*/
|
||||
#define OS_ERRNO_HWI_FASTMODE_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x07)
|
||||
|
||||
#if (OS_HWI_WITH_ARG == 1)
|
||||
/* *
|
||||
* @ingroup los_hwi
|
||||
* Set interrupt vector table.
|
||||
*/
|
||||
extern VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector, VOID *arg);
|
||||
#else
|
||||
/* *
|
||||
* @ingroup los_hwi
|
||||
* Set interrupt vector table.
|
||||
*/
|
||||
extern VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector);
|
||||
#endif
|
||||
|
||||
/* *
|
||||
* @ingroup los_arch_interrupt
|
||||
* @brief: Hardware interrupt entry function.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used as all hardware interrupt handling function entry.
|
||||
*
|
||||
* @attention:
|
||||
* <ul><li>None.</li></ul>
|
||||
*
|
||||
* @param:None.
|
||||
*
|
||||
* @retval:None.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_arch_interrupt.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see None.
|
||||
*/
|
||||
extern VOID HalInterrupt(VOID);
|
||||
|
||||
/* *
|
||||
* @ingroup los_arch_interrupt
|
||||
* @brief: Get an interrupt number.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to get the current interrupt number.
|
||||
*
|
||||
* @attention:
|
||||
* <ul><li>None.</li></ul>
|
||||
*
|
||||
* @param: None.
|
||||
*
|
||||
* @retval: Interrupt Indexes number.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_arch_interrupt.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see None.
|
||||
*/
|
||||
extern UINT32 HalIntNumGet(VOID);
|
||||
|
||||
/* *
|
||||
* @ingroup los_arch_interrupt
|
||||
* @brief: Default vector handling function.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to configure interrupt for null function.
|
||||
*
|
||||
* @attention:
|
||||
* <ul><li>None.</li></ul>
|
||||
*
|
||||
* @param:None.
|
||||
*
|
||||
* @retval:None.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_arch_interrupt.h: the header file that contains the API declaration.</li
|
||||
></ul>
|
||||
* @see None.
|
||||
*/
|
||||
extern VOID HalHwiDefaultHandler(VOID);
|
||||
|
||||
#define OS_EXC_IN_INIT 0
|
||||
#define OS_EXC_IN_TASK 1
|
||||
#define OS_EXC_IN_HWI 2
|
||||
|
||||
#define OS_EXC_FLAG_FAULTADDR_VALID 0x01
|
||||
#define OS_EXC_FLAG_IN_HWI 0x02
|
||||
|
||||
#define OS_EXC_IMPRECISE_ACCESS_ADDR 0xABABABAB
|
||||
|
||||
/**
|
||||
* @ingroup los_exc
|
||||
* the struct of register files
|
||||
*
|
||||
* description: the register files that saved when exception triggered
|
||||
*
|
||||
* notes:the following register with prefix 'uw' correspond to the registers in the cpu data sheet.
|
||||
*/
|
||||
typedef struct TagExcContext {
|
||||
UINT32 spsr;
|
||||
UINT32 r0;
|
||||
UINT32 r1;
|
||||
UINT32 r2;
|
||||
UINT32 r3;
|
||||
UINT32 r4;
|
||||
UINT32 r5;
|
||||
UINT32 r6;
|
||||
UINT32 r7;
|
||||
UINT32 r8;
|
||||
UINT32 r9;
|
||||
UINT32 r10;
|
||||
UINT32 r11;
|
||||
UINT32 r12;
|
||||
UINT32 sp;
|
||||
UINT32 lr;
|
||||
UINT32 pc;
|
||||
} EXC_CONTEXT_S;
|
||||
|
||||
typedef VOID (*EXC_PROC_FUNC)(UINT32, EXC_CONTEXT_S *);
|
||||
VOID HalExcHandleEntry(UINT32 excType, UINT32 faultAddr, UINT32 pid, EXC_CONTEXT_S *excBufAddr);
|
||||
VOID HalHwiInit();
|
||||
|
||||
/**
|
||||
* @ingroup los_exc
|
||||
* exception types: undefined instruction exception.
|
||||
*/
|
||||
#define OS_EXCEPT_UNDEF_INSTR 1
|
||||
|
||||
/**
|
||||
* @ingroup los_exc
|
||||
* exception types: software interrupt.
|
||||
*/
|
||||
#define OS_EXCEPT_SWI 2
|
||||
|
||||
/**
|
||||
* @ingroup los_exc
|
||||
* exception types: prefetch abort exception.
|
||||
*/
|
||||
#define OS_EXCEPT_PREFETCH_ABORT 3
|
||||
|
||||
/**
|
||||
* @ingroup los_exc
|
||||
* exception types: data abort exception.
|
||||
*/
|
||||
#define OS_EXCEPT_DATA_ABORT 4
|
||||
|
||||
/**
|
||||
* @ingroup los_exc
|
||||
* exception types: FIQ exception.
|
||||
*/
|
||||
#define OS_EXCEPT_FIQ 5
|
||||
|
||||
/**
|
||||
* @ingroup los_exc
|
||||
* Exception information structure
|
||||
*
|
||||
* Description: Exception information saved when an exception is triggered on the Cortex-M4 platform.
|
||||
*
|
||||
*/
|
||||
typedef struct TagExcInfo {
|
||||
/**< Exception occurrence phase: 0 means that an exception occurs in initialization, 1 means that an exception occurs in a task, and 2 means that an exception occurs in an interrupt */
|
||||
UINT16 phase;
|
||||
/**< Exception type. When exceptions occur, check the numbers 1 - 19 listed above */
|
||||
UINT16 type;
|
||||
/**< If the exact address access error indicates the wrong access address when the exception occurred */
|
||||
UINT32 faultAddr;
|
||||
/**< An exception occurs in an interrupt, indicating the interrupt number. An exception occurs in the task, indicating the task ID, or 0xFFFFFFFF if it occurs during initialization */
|
||||
UINT32 thrdPid;
|
||||
/**< Number of nested exceptions. Currently only registered hook functions are supported when an exception is entered for the first time */
|
||||
UINT16 nestCnt;
|
||||
/**< reserve */
|
||||
UINT16 reserved;
|
||||
/**< Hardware context at the time an exception to the automatic stack floating-point register occurs */
|
||||
EXC_CONTEXT_S *context;
|
||||
} ExcInfo;
|
||||
|
||||
extern UINT32 g_intCount;
|
||||
extern ExcInfo g_excInfo;
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_ARCH_INTERRUPT_H */
|
||||
53
kernel/arch/arm/arm9/gcc/los_arch_timer.h
Normal file
53
kernel/arch/arm/arm9/gcc/los_arch_timer.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_ARCH_TIMER_H
|
||||
#define _LOS_ARCH_TIMER_H
|
||||
|
||||
#include "los_config.h"
|
||||
#include "los_compiler.h"
|
||||
#include "los_context.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
UINT32 HalTickStart(OS_TICK_HANDLER handler);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_ARCH_TIMER_H */
|
||||
158
kernel/arch/arm/arm9/gcc/los_context.c
Normal file
158
kernel/arch/arm/arm9/gcc/los_context.c
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_context.h"
|
||||
#include "securec.h"
|
||||
#include "los_arch_context.h"
|
||||
#include "los_arch_interrupt.h"
|
||||
#include "los_task.h"
|
||||
#include "los_sched.h"
|
||||
#include "los_interrupt.h"
|
||||
#include "los_arch_timer.h"
|
||||
#include "los_debug.h"
|
||||
|
||||
/* ****************************************************************************
|
||||
Function : HalArchInit
|
||||
Description : arch init function
|
||||
Input : None
|
||||
Output : None
|
||||
Return : None
|
||||
**************************************************************************** */
|
||||
LITE_OS_SEC_TEXT_INIT VOID HalArchInit(VOID)
|
||||
{
|
||||
UINT32 ret;
|
||||
HalHwiInit();
|
||||
|
||||
ret = HalTickStart(OsTickHandler);
|
||||
if (ret != LOS_OK) {
|
||||
PRINT_ERR("Tick start failed!\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* ****************************************************************************
|
||||
Function : HalSysExit
|
||||
Description : Task exit function
|
||||
Input : None
|
||||
Output : None
|
||||
Return : None
|
||||
**************************************************************************** */
|
||||
LITE_OS_SEC_TEXT_MINOR VOID HalSysExit(VOID)
|
||||
{
|
||||
LOS_IntLock();
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
/* ****************************************************************************
|
||||
Function : HalTskStackInit
|
||||
Description : Task stack initialization function
|
||||
Input : taskID --- TaskID
|
||||
stackSize --- Total size of the stack
|
||||
topStack --- Top of task's stack
|
||||
Output : None
|
||||
Return : Context pointer
|
||||
**************************************************************************** */
|
||||
LITE_OS_SEC_TEXT_INIT VOID *HalTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack)
|
||||
{
|
||||
TaskContext *context = NULL;
|
||||
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
|
||||
errno_t result;
|
||||
|
||||
/* initialize the task stack, write magic num to stack top */
|
||||
result = memset_s(topStack, stackSize, (INT32)(OS_TASK_STACK_INIT & 0xFF), stackSize);
|
||||
if (result != EOK) {
|
||||
PRINT_ERR("memset_s is failed:%s[%d]\r\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
*((UINT32 *)(topStack)) = OS_TASK_MAGIC_WORD;
|
||||
|
||||
context = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext));
|
||||
|
||||
context->r0 = taskID;
|
||||
context->r1 = 0x01010101L;
|
||||
context->r2 = 0x02020202L;
|
||||
context->r3 = 0x03030303L;
|
||||
context->r4 = 0x04040404L;
|
||||
context->r5 = 0x05050505L;
|
||||
context->r6 = 0x06060606L;
|
||||
context->r7 = 0x07070707L;
|
||||
context->r8 = 0x08080808L;
|
||||
context->r9 = 0x09090909L;
|
||||
context->r10 = 0x10101010L;
|
||||
context->r11 = 0x11111111L;
|
||||
context->r12 = 0x12121212L;
|
||||
context->sp = (UINTPTR)topStack + stackSize;
|
||||
context->lr = (UINTPTR)HalSysExit;
|
||||
|
||||
if ((UINTPTR)taskCB->taskEntry & 0x01) {
|
||||
context->pc = (UINTPTR)OsTaskEntryThumb;
|
||||
context->spsr = PSR_MODE_SYS_THUMB; /* thumb mode */
|
||||
} else {
|
||||
context->pc = (UINTPTR)OsTaskEntryArm;
|
||||
context->spsr = PSR_MODE_SYS_ARM; /* arm mode */
|
||||
}
|
||||
|
||||
return (VOID *)context;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 HalStartSchedule(VOID)
|
||||
{
|
||||
(VOID)LOS_IntLock();
|
||||
OsSchedStart();
|
||||
HalStartToRun();
|
||||
|
||||
return LOS_OK; /* never return */
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT VOID HalTaskSchedule(VOID)
|
||||
{
|
||||
__asm__ __volatile__("swi 0");
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT VOID dmb(VOID)
|
||||
{
|
||||
__asm__ __volatile__("" : : : "memory");
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT VOID dsb(VOID)
|
||||
{
|
||||
__asm__ __volatile__("mcr p15, 0, %0, c7, c10, 4" : : "r"(0) : "memory");
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT VOID isb(VOID)
|
||||
{
|
||||
__asm__ __volatile__("" : : : "memory");
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT VOID wfi(VOID)
|
||||
{
|
||||
__asm__ __volatile__("mcr p15, 0, %0, c7, c0, 4" : : "r"(0) : "memory");
|
||||
}
|
||||
|
||||
182
kernel/arch/arm/arm9/gcc/los_dispatch.S
Normal file
182
kernel/arch/arm/arm9/gcc/los_dispatch.S
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
.equ OS_PSR_THUMB, 0x20
|
||||
.equ OS_PSR_INT_DIS, 0xC0
|
||||
.equ OS_PSR_FIQ_DIS, 0x40
|
||||
.equ OS_PSR_IRQ_DIS, 0x80
|
||||
.equ OS_PSR_MODE_MASK, 0x1F
|
||||
.equ OS_PSR_MODE_USR, 0x10
|
||||
.equ OS_PSR_MODE_FIQ, 0x11
|
||||
.equ OS_PSR_MODE_IRQ, 0x12
|
||||
.equ OS_PSR_MODE_SVC, 0x13
|
||||
.equ OS_PSR_MODE_ABT, 0x17
|
||||
.equ OS_PSR_MODE_UND, 0x1B
|
||||
.equ OS_PSR_MODE_SYS, 0x1F
|
||||
|
||||
.global HalStartToRun
|
||||
.global OsTaskEntryArm
|
||||
.global OsTaskEntryThumb
|
||||
.global HalExceptSwiHdl
|
||||
.global HalExceptFiqHdl
|
||||
.global HalExceptIrqHdl
|
||||
|
||||
.extern OsTaskEntry
|
||||
.extern OsSchedTaskSwitch
|
||||
.extern HalInterrupt
|
||||
.extern g_losTask
|
||||
|
||||
.code 32
|
||||
.text
|
||||
|
||||
.macro SAVE_CONTEXT
|
||||
STMFD SP!, {R0}
|
||||
|
||||
MRS R0, SPSR
|
||||
AND R0, R0, #OS_PSR_MODE_SYS
|
||||
CMP R0, #OS_PSR_MODE_SYS
|
||||
BNE 1f
|
||||
|
||||
STMFD SP!, {SP}^
|
||||
LDMFD SP!, {R0}
|
||||
|
||||
STMFD R0!, {LR}
|
||||
MOV LR, R0
|
||||
LDMFD SP!, {R0}
|
||||
|
||||
STMFD LR, {R0-R14}^
|
||||
|
||||
SUB LR, LR, #60
|
||||
MRS R0, SPSR
|
||||
STMFD LR!, {R0}
|
||||
|
||||
LDR R1, =g_losTask
|
||||
LDR R1, [R1]
|
||||
STR LR, [R1]
|
||||
B 2f
|
||||
|
||||
1:
|
||||
LDMFD SP!, {R0}
|
||||
STMFD SP!, {R0-R12, LR}
|
||||
MRS R0, SPSR
|
||||
STMFD SP!, {R0}
|
||||
|
||||
2:
|
||||
.endm
|
||||
|
||||
.macro RETSORE_CONTEXT
|
||||
MRS R0, SPSR
|
||||
AND R0, R0, #OS_PSR_MODE_SYS
|
||||
CMP R0, #OS_PSR_MODE_SYS
|
||||
BNE 3f
|
||||
|
||||
LDR R1, =g_losTask
|
||||
LDR R1, [R1]
|
||||
LDR LR, [R1]
|
||||
|
||||
LDMFD LR!, {R0}
|
||||
MSR SPSR_cxsf, R0
|
||||
LDMFD LR, {R0-R14}^
|
||||
ADD LR, LR, #60
|
||||
LDMFD LR!, {PC}^
|
||||
3:
|
||||
LDMFD SP!, {R0}
|
||||
MSR SPSR_cxsf, R0
|
||||
LDMFD SP!, {R0-R12, LR}
|
||||
MOVS PC, LR
|
||||
.endm
|
||||
|
||||
.macro TASK_SWITCH
|
||||
MRS R0, CPSR
|
||||
ORR R0, R0, #OS_PSR_INT_DIS
|
||||
MSR CPSR, R0
|
||||
BLX OsSchedTaskSwitch
|
||||
CMP R0, #0
|
||||
BEQ 4f
|
||||
|
||||
LDR R0, =g_losTask
|
||||
LDR R1, [R0, #4]
|
||||
STR R1, [R0]
|
||||
|
||||
4:
|
||||
.endm
|
||||
|
||||
HalStartToRun:
|
||||
LDR R1, =g_losTask
|
||||
LDR R0, [R1, #4]
|
||||
LDR LR, [R0]
|
||||
|
||||
LDMFD LR!, {R0}
|
||||
MSR SPSR_cxsf, R0
|
||||
|
||||
LDMFD LR, {R0-R14}^
|
||||
ADD LR, LR, #60
|
||||
LDMFD LR!, {PC}^
|
||||
|
||||
HalExceptSwiHdl:
|
||||
SAVE_CONTEXT
|
||||
|
||||
TASK_SWITCH
|
||||
|
||||
RETSORE_CONTEXT
|
||||
|
||||
HalExceptFiqHdl:
|
||||
SUB LR, LR, #4
|
||||
SAVE_CONTEXT
|
||||
|
||||
BLX HalInterrupt
|
||||
|
||||
RETSORE_CONTEXT
|
||||
|
||||
HalExceptIrqHdl:
|
||||
SUB LR, LR, #4
|
||||
|
||||
SAVE_CONTEXT
|
||||
|
||||
BLX HalInterrupt
|
||||
|
||||
RETSORE_CONTEXT
|
||||
|
||||
OsTaskEntryArm:
|
||||
STMFD SP!, {LR}
|
||||
BL OsTaskEntry
|
||||
LDMFD SP!, {LR}
|
||||
BX LR
|
||||
|
||||
.code 16
|
||||
.text
|
||||
OsTaskEntryThumb:
|
||||
PUSH {LR}
|
||||
BL OsTaskEntry
|
||||
POP {R0}
|
||||
MOV LR, R0
|
||||
BX LR
|
||||
|
||||
132
kernel/arch/arm/arm9/gcc/los_exc.S
Normal file
132
kernel/arch/arm/arm9/gcc/los_exc.S
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
.equ OS_PSR_INT_DIS, 0xC0
|
||||
.equ OS_PSR_FIQ_DIS, 0x40
|
||||
.equ OS_PSR_IRQ_DIS, 0x80
|
||||
.equ OS_PSR_MODE_MASK, 0x1F
|
||||
.equ OS_PSR_MODE_USR, 0x10
|
||||
.equ OS_PSR_MODE_FIQ, 0x11
|
||||
.equ OS_PSR_MODE_IRQ, 0x12
|
||||
.equ OS_PSR_MODE_SVC, 0x13
|
||||
.equ OS_PSR_MODE_ABT, 0x17
|
||||
.equ OS_PSR_MODE_UND, 0x1B
|
||||
.equ OS_PSR_MODE_SYS, 0x1F
|
||||
|
||||
.equ OS_EXCEPT_RESET, 0x00
|
||||
.equ OS_EXCEPT_UNDEF_INSTR, 0x01
|
||||
.equ OS_EXCEPT_SWI, 0x02
|
||||
.equ OS_EXCEPT_PREFETCH_ABORT, 0x03
|
||||
.equ OS_EXCEPT_DATA_ABORT, 0x04
|
||||
.equ OS_EXCEPT_FIQ, 0x05
|
||||
.equ OS_EXCEPT_ADDR_ABORT, 0x06
|
||||
.equ OS_EXCEPT_IRQ, 0x07
|
||||
|
||||
.global HalExceptAddrAbortHdl
|
||||
.global HalExceptDataAbortHdl
|
||||
.global HalExceptPrefetchAbortHdl
|
||||
.global HalExceptUndefInstrHdl
|
||||
|
||||
.extern HalExcHandleEntry
|
||||
.extern __exc_stack_top
|
||||
|
||||
.code 32
|
||||
.text
|
||||
|
||||
HalExceptUndefInstrHdl:
|
||||
STMFD SP!, {R0-R5}
|
||||
MOV R0, #OS_EXCEPT_UNDEF_INSTR
|
||||
B _osExceptDispatch
|
||||
|
||||
HalExceptPrefetchAbortHdl:
|
||||
SUB LR, LR, #4
|
||||
STMFD SP!, {R0-R5}
|
||||
|
||||
MOV R0, #OS_EXCEPT_PREFETCH_ABORT
|
||||
|
||||
B _osExceptDispatch
|
||||
|
||||
HalExceptDataAbortHdl:
|
||||
SUB LR, LR, #4
|
||||
STMFD SP!, {R0-R5}
|
||||
|
||||
MOV R0, #OS_EXCEPT_DATA_ABORT
|
||||
|
||||
B _osExceptDispatch
|
||||
|
||||
HalExceptAddrAbortHdl:
|
||||
SUB LR, LR, #8
|
||||
STMFD SP!, {R0-R5}
|
||||
|
||||
MOV R0, #OS_EXCEPT_ADDR_ABORT
|
||||
|
||||
B _osExceptDispatch
|
||||
|
||||
_osExceptDispatch:
|
||||
MRS R1, SPSR
|
||||
MOV R2, LR
|
||||
MOV R4, SP
|
||||
ADD SP, SP, #(6 * 4)
|
||||
|
||||
MSR CPSR_c, #(OS_PSR_INT_DIS | OS_PSR_MODE_SVC)
|
||||
MOV R3, SP
|
||||
LDR SP, =__exc_stack_top
|
||||
|
||||
STMFD SP!, {R2}
|
||||
STMFD SP!, {LR}
|
||||
STMFD SP!, {R3}
|
||||
STMFD SP!, {R6-R12}
|
||||
LDMFD R4!, {R6-R12}
|
||||
STMFD SP!, {R6-R11}
|
||||
STMFD SP!, {R1}
|
||||
MOV R3, SP
|
||||
|
||||
_osExceptionGetSP:
|
||||
STMFD SP!, {R1}
|
||||
LDR R2, =HalExcHandleEntry
|
||||
|
||||
MOV LR, PC
|
||||
BX R2
|
||||
|
||||
LDMFD SP!, {R1}
|
||||
MOV SP, R1
|
||||
|
||||
LDMFD SP!, {R1}
|
||||
MSR CPSR, R1
|
||||
LDMFD SP!, {R0-R12}
|
||||
ADD SP, SP, #(4 * 2)
|
||||
LDMFD SP!, {LR}
|
||||
SUB SP, SP, #(4 * 3)
|
||||
LDMFD SP, {SP}
|
||||
ADD LR, LR, #4
|
||||
MOV PC, LR
|
||||
|
||||
.end
|
||||
480
kernel/arch/arm/arm9/gcc/los_interrupt.c
Normal file
480
kernel/arch/arm/arm9/gcc/los_interrupt.c
Normal file
@@ -0,0 +1,480 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "los_interrupt.h"
|
||||
#include <stdarg.h>
|
||||
#include "securec.h"
|
||||
#include "los_context.h"
|
||||
#include "los_arch_interrupt.h"
|
||||
#include "los_debug.h"
|
||||
#include "los_hook.h"
|
||||
#include "los_task.h"
|
||||
#include "los_sched.h"
|
||||
#include "los_memory.h"
|
||||
#include "los_membox.h"
|
||||
#include "los_reg.h"
|
||||
|
||||
#define OS_INT_IRQ_ENABLE (1U << 0)
|
||||
#define OS_INT_FIQ_ENABLE (1U << 1)
|
||||
#define OS_INT_REG_BASE 0x00802040UL
|
||||
#define OS_INT_GLOBAL_ENABLE_ADDR (OS_INT_REG_BASE + 4)
|
||||
#define OS_INT_ENABLE_ADDR (OS_INT_REG_BASE)
|
||||
#define OS_INT_STATUS_ADDR (OS_INT_REG_BASE + 12)
|
||||
|
||||
#define OS_INT_ENABLE(num) (*((volatile UINT32 *)OS_INT_ENABLE_ADDR) |= (1U << (num)))
|
||||
#define OS_INT_DISABLE(num) (*((volatile UINT32 *)OS_INT_ENABLE_ADDR) &= ~(1U << (num)))
|
||||
|
||||
#define OS_INSTR_SET_MASK 0x01000020U
|
||||
#define OS_ARM_INSTR_LEN 4
|
||||
#define OS_THUMB_INSTR_LEN 2
|
||||
|
||||
UINT32 g_intCount = 0;
|
||||
ExcInfo g_excInfo = {0};
|
||||
|
||||
/* *
|
||||
* @ingroup los_hwi
|
||||
* hardware interrupt form mapping handling function array.
|
||||
*/
|
||||
STATIC HWI_PROC_FUNC g_hwiForm[OS_VECTOR_CNT] = {0};
|
||||
|
||||
#if (OS_HWI_WITH_ARG == 1)
|
||||
|
||||
typedef struct {
|
||||
HWI_PROC_FUNC pfnHandler;
|
||||
VOID *pParm;
|
||||
} HWI_HANDLER_FUNC;
|
||||
|
||||
/* *
|
||||
* @ingroup los_hwi
|
||||
* hardware interrupt handler form mapping handling function array.
|
||||
*/
|
||||
STATIC HWI_HANDLER_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {{ (HWI_PROC_FUNC)0, (HWI_ARG_T)0 }};
|
||||
|
||||
/* *
|
||||
* @ingroup los_hwi
|
||||
* Set interrupt vector table.
|
||||
*/
|
||||
VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector, VOID *arg)
|
||||
{
|
||||
if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) {
|
||||
g_hwiForm[num + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)HalInterrupt;
|
||||
g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pfnHandler = vector;
|
||||
g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pParm = arg;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
/* *
|
||||
* @ingroup los_hwi
|
||||
* hardware interrupt handler form mapping handling function array.
|
||||
*/
|
||||
STATIC HWI_PROC_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {0};
|
||||
|
||||
/* *
|
||||
* @ingroup los_hwi
|
||||
* Set interrupt vector table.
|
||||
*/
|
||||
VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector)
|
||||
{
|
||||
if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) {
|
||||
g_hwiForm[num + OS_SYS_VECTOR_CNT] = HalInterrupt;
|
||||
g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT] = vector;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* ****************************************************************************
|
||||
Function : HalIntNumGet
|
||||
Description : Get an interrupt number
|
||||
Input : None
|
||||
Output : None
|
||||
Return : Interrupt Indexes number
|
||||
**************************************************************************** */
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 HalIntNumGet(VOID)
|
||||
{
|
||||
UINT32 status;
|
||||
|
||||
READ_UINT32(status, OS_INT_STATUS_ADDR);
|
||||
return (31 - CLZ(status)); /* 31 bit map of int */
|
||||
}
|
||||
|
||||
inline UINT32 HalIsIntActive(VOID)
|
||||
{
|
||||
return (g_intCount > 0);
|
||||
}
|
||||
/* ****************************************************************************
|
||||
Function : HalHwiDefaultHandler
|
||||
Description : default handler of the hardware interrupt
|
||||
Input : None
|
||||
Output : None
|
||||
Return : None
|
||||
**************************************************************************** */
|
||||
/*lint -e529*/
|
||||
LITE_OS_SEC_TEXT_MINOR VOID HalHwiDefaultHandler(VOID)
|
||||
{
|
||||
PRINT_ERR("%s irqnum:%u\n", __FUNCTION__, HalIntNumGet());
|
||||
while (1) {}
|
||||
}
|
||||
|
||||
WEAK VOID HalPreInterruptHandler(UINT32 arg)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WEAK VOID HalAftInterruptHandler(UINT32 arg)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* ****************************************************************************
|
||||
Function : HalInterrupt
|
||||
Description : Hardware interrupt entry function
|
||||
Input : None
|
||||
Output : None
|
||||
Return : None
|
||||
**************************************************************************** */
|
||||
LITE_OS_SEC_TEXT VOID HalInterrupt(VOID)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINT32 hwiIndex;
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
g_intCount++;
|
||||
LOS_IntRestore(intSave);
|
||||
|
||||
#if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
|
||||
OsSchedUpdateSleepTime();
|
||||
#endif
|
||||
|
||||
hwiIndex = HalIntNumGet();
|
||||
|
||||
OsHookCall(LOS_HOOK_TYPE_ISR_ENTER, hwiIndex);
|
||||
|
||||
HalPreInterruptHandler(hwiIndex);
|
||||
|
||||
#if (OS_HWI_WITH_ARG == 1)
|
||||
if (g_hwiHandlerForm[hwiIndex].pfnHandler != 0) {
|
||||
g_hwiHandlerForm[hwiIndex].pfnHandler((VOID *)g_hwiHandlerForm[hwiIndex].pParm);
|
||||
}
|
||||
#else
|
||||
if (g_hwiHandlerForm[hwiIndex] != 0) {
|
||||
g_hwiHandlerForm[hwiIndex]();
|
||||
}
|
||||
#endif
|
||||
|
||||
HalAftInterruptHandler(hwiIndex);
|
||||
|
||||
OsHookCall(LOS_HOOK_TYPE_ISR_EXIT, hwiIndex);
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
g_intCount--;
|
||||
LOS_IntRestore(intSave);
|
||||
}
|
||||
|
||||
/* ****************************************************************************
|
||||
Function : HalHwiCreate
|
||||
Description : create hardware interrupt
|
||||
Input : hwiNum --- hwi num to create
|
||||
hwiPrio --- priority of the hwi
|
||||
mode --- unused
|
||||
handler --- hwi handler
|
||||
arg --- param of the hwi handler
|
||||
Output : None
|
||||
Return : LOS_OK on success or error code on failure
|
||||
**************************************************************************** */
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 HalHwiCreate(HWI_HANDLE_T hwiNum,
|
||||
HWI_PRIOR_T hwiPrio,
|
||||
HWI_MODE_T mode,
|
||||
HWI_PROC_FUNC handler,
|
||||
HWI_ARG_T arg)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
if (handler == NULL) {
|
||||
return OS_ERRNO_HWI_PROC_FUNC_NULL;
|
||||
}
|
||||
|
||||
if (hwiNum >= OS_HWI_MAX_NUM) {
|
||||
return OS_ERRNO_HWI_NUM_INVALID;
|
||||
}
|
||||
|
||||
if (g_hwiForm[hwiNum + OS_SYS_VECTOR_CNT] != (HWI_PROC_FUNC)HalHwiDefaultHandler) {
|
||||
return OS_ERRNO_HWI_ALREADY_CREATED;
|
||||
}
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
#if (OS_HWI_WITH_ARG == 1)
|
||||
OsSetVector(hwiNum, handler, arg);
|
||||
#else
|
||||
OsSetVector(hwiNum, handler);
|
||||
#endif
|
||||
OS_INT_ENABLE(hwiNum);
|
||||
LOS_IntRestore(intSave);
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
/* ****************************************************************************
|
||||
Function : HalHwiDelete
|
||||
Description : Delete hardware interrupt
|
||||
Input : hwiNum --- hwi num to delete
|
||||
Output : None
|
||||
Return : LOS_OK on success or error code on failure
|
||||
**************************************************************************** */
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 HalHwiDelete(HWI_HANDLE_T hwiNum)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
if (hwiNum >= OS_HWI_MAX_NUM) {
|
||||
return OS_ERRNO_HWI_NUM_INVALID;
|
||||
}
|
||||
|
||||
OS_INT_DISABLE(hwiNum);
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
g_hwiForm[hwiNum + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)HalHwiDefaultHandler;
|
||||
LOS_IntRestore(intSave);
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
#if (LOSCFG_KERNEL_PRINTF != 0)
|
||||
STATIC VOID OsExcTypeInfo(const ExcInfo *excInfo)
|
||||
{
|
||||
CHAR *phaseStr[] = {"exc in init", "exc in task", "exc in hwi"};
|
||||
|
||||
PRINTK("Type = %u\n", excInfo->type);
|
||||
PRINTK("ThrdPid = %u\n", excInfo->thrdPid);
|
||||
PRINTK("Phase = %s\n", phaseStr[excInfo->phase]);
|
||||
PRINTK("FaultAddr = 0x%x\n", excInfo->faultAddr);
|
||||
}
|
||||
|
||||
STATIC VOID OsExcCurTaskInfo(const ExcInfo *excInfo)
|
||||
{
|
||||
PRINTK("Current task info:\n");
|
||||
if (excInfo->phase == OS_EXC_IN_TASK) {
|
||||
LosTaskCB *taskCB = OS_TCB_FROM_TID(LOS_CurTaskIDGet());
|
||||
PRINTK("Task name = %s\n", taskCB->taskName);
|
||||
PRINTK("Task ID = %u\n", taskCB->taskID);
|
||||
PRINTK("Task SP = 0x%x\n", taskCB->stackPointer);
|
||||
PRINTK("Task ST = 0x%x\n", taskCB->topOfStack);
|
||||
PRINTK("Task SS = 0x%x\n", taskCB->stackSize);
|
||||
} else if (excInfo->phase == OS_EXC_IN_HWI) {
|
||||
PRINTK("Exception occur in interrupt phase!\n");
|
||||
} else {
|
||||
PRINTK("Exception occur in system init phase!\n");
|
||||
}
|
||||
}
|
||||
|
||||
STATIC VOID OsExcRegInfo(const ExcInfo *excInfo)
|
||||
{
|
||||
PRINTK("Exception reg dump:\n");
|
||||
PRINTK("PC = 0x%x\n", excInfo->context->pc);
|
||||
PRINTK("LR = 0x%x\n", excInfo->context->lr);
|
||||
PRINTK("R0 = 0x%x\n", excInfo->context->r0);
|
||||
PRINTK("R1 = 0x%x\n", excInfo->context->r1);
|
||||
PRINTK("R2 = 0x%x\n", excInfo->context->r2);
|
||||
PRINTK("R3 = 0x%x\n", excInfo->context->r3);
|
||||
PRINTK("R4 = 0x%x\n", excInfo->context->r4);
|
||||
PRINTK("R5 = 0x%x\n", excInfo->context->r5);
|
||||
PRINTK("R6 = 0x%x\n", excInfo->context->r6);
|
||||
PRINTK("R7 = 0x%x\n", excInfo->context->r7);
|
||||
PRINTK("R8 = 0x%x\n", excInfo->context->r8);
|
||||
PRINTK("R9 = 0x%x\n", excInfo->context->r9);
|
||||
PRINTK("R10 = 0x%x\n", excInfo->context->r10);
|
||||
PRINTK("R11 = 0x%x\n", excInfo->context->r11);
|
||||
PRINTK("R12 = 0x%x\n", excInfo->context->r12);
|
||||
PRINTK("xPSR = 0x%x\n", excInfo->context->spsr);
|
||||
}
|
||||
|
||||
STATIC VOID OsExcBackTraceInfo(const ExcInfo *excInfo)
|
||||
{
|
||||
UINTPTR LR[LOSCFG_BACKTRACE_DEPTH] = {0};
|
||||
UINT32 index;
|
||||
|
||||
OsBackTraceHookCall(LR, LOSCFG_BACKTRACE_DEPTH, 0, excInfo->context->sp);
|
||||
|
||||
PRINTK("----- backtrace start -----\n");
|
||||
for (index = 0; index < LOSCFG_BACKTRACE_DEPTH; index++) {
|
||||
if (LR[index] == 0) {
|
||||
break;
|
||||
}
|
||||
PRINTK("backtrace %u -- lr = 0x%x\n", index, LR[index]);
|
||||
}
|
||||
PRINTK("----- backtrace end -----\n");
|
||||
}
|
||||
|
||||
STATIC VOID OsExcMemPoolCheckInfo(VOID)
|
||||
{
|
||||
PRINTK("\r\nmemory pools check:\n");
|
||||
#if (LOSCFG_PLATFORM_EXC == 1)
|
||||
MemInfoCB memExcInfo[OS_SYS_MEM_NUM];
|
||||
UINT32 errCnt;
|
||||
UINT32 i;
|
||||
|
||||
(VOID)memset_s(memExcInfo, sizeof(memExcInfo), 0, sizeof(memExcInfo));
|
||||
|
||||
errCnt = OsMemExcInfoGet(OS_SYS_MEM_NUM, memExcInfo);
|
||||
if (errCnt < OS_SYS_MEM_NUM) {
|
||||
errCnt += OsMemboxExcInfoGet(OS_SYS_MEM_NUM - errCnt, memExcInfo + errCnt);
|
||||
}
|
||||
|
||||
if (errCnt == 0) {
|
||||
PRINTK("all memory pool check passed!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < errCnt; i++) {
|
||||
PRINTK("pool num = %u\n", i);
|
||||
PRINTK("pool type = %d\n", memExcInfo[i].type);
|
||||
PRINTK("pool addr = 0x%x\n", memExcInfo[i].startAddr);
|
||||
PRINTK("pool size = 0x%x\n", memExcInfo[i].size);
|
||||
PRINTK("pool free = 0x%x\n", memExcInfo[i].free);
|
||||
PRINTK("pool blkNum = %u\n", memExcInfo[i].blockSize);
|
||||
PRINTK("pool error node addr = 0x%x\n", memExcInfo[i].errorAddr);
|
||||
PRINTK("pool error node len = 0x%x\n", memExcInfo[i].errorLen);
|
||||
PRINTK("pool error node owner = %u\n", memExcInfo[i].errorOwner);
|
||||
}
|
||||
#endif
|
||||
UINT32 ret = LOS_MemIntegrityCheck(LOSCFG_SYS_HEAP_ADDR);
|
||||
if (ret == LOS_OK) {
|
||||
PRINTK("system heap memcheck over, all passed!\n");
|
||||
}
|
||||
|
||||
PRINTK("memory pool check end!\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
STATIC VOID OsExcInfoDisplay(const ExcInfo *excInfo)
|
||||
{
|
||||
#if (LOSCFG_KERNEL_PRINTF != 0)
|
||||
PRINTK("*************Exception Information**************\n");
|
||||
OsExcTypeInfo(excInfo);
|
||||
OsExcCurTaskInfo(excInfo);
|
||||
OsExcRegInfo(excInfo);
|
||||
OsExcBackTraceInfo(excInfo);
|
||||
OsGetAllTskInfo();
|
||||
OsExcMemPoolCheckInfo();
|
||||
#endif
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT VOID HalExcHandleEntry(UINT32 excType, UINT32 faultAddr, UINT32 pid, EXC_CONTEXT_S *excBufAddr)
|
||||
{
|
||||
g_intCount++;
|
||||
g_excInfo.nestCnt++;
|
||||
|
||||
g_excInfo.type = excType;
|
||||
|
||||
if ((excType == OS_EXCEPT_UNDEF_INSTR) || (excType == OS_EXCEPT_SWI)) {
|
||||
if ((excBufAddr->spsr & OS_INSTR_SET_MASK) == 0) { /* Work status: ARM */
|
||||
excBufAddr->pc -= OS_ARM_INSTR_LEN;
|
||||
} else if ((excBufAddr->spsr & OS_INSTR_SET_MASK) == 0x20) { /* Work status: Thumb */
|
||||
excBufAddr->pc -= OS_THUMB_INSTR_LEN;
|
||||
}
|
||||
}
|
||||
g_excInfo.faultAddr = OS_EXC_IMPRECISE_ACCESS_ADDR;
|
||||
|
||||
if (g_losTask.runTask != NULL) {
|
||||
g_excInfo.phase = OS_EXC_IN_TASK;
|
||||
g_excInfo.thrdPid = g_losTask.runTask->taskID;
|
||||
} else {
|
||||
g_excInfo.phase = OS_EXC_IN_INIT;
|
||||
g_excInfo.thrdPid = OS_NULL_INT;
|
||||
}
|
||||
g_excInfo.context = excBufAddr;
|
||||
|
||||
OsDoExcHook(EXC_INTERRUPT);
|
||||
OsExcInfoDisplay(&g_excInfo);
|
||||
HalSysExit();
|
||||
}
|
||||
|
||||
/* ****************************************************************************
|
||||
Function : HalHwiInit
|
||||
Description : initialization of the hardware interrupt
|
||||
Input : None
|
||||
Output : None
|
||||
Return : None
|
||||
**************************************************************************** */
|
||||
LITE_OS_SEC_TEXT_INIT VOID HalHwiInit(VOID)
|
||||
{
|
||||
#if (LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT == 1)
|
||||
UINT32 reg;
|
||||
UINT32 val;
|
||||
|
||||
for (val = OS_SYS_VECTOR_CNT; val < OS_VECTOR_CNT; val++) {
|
||||
#if (OS_HWI_WITH_ARG == 1)
|
||||
g_hwiForm[val].pfnHook = HalHwiDefaultHandler;
|
||||
g_hwiForm[val].uwParam = 0;
|
||||
#else
|
||||
g_hwiForm[val] = (HWI_PROC_FUNC)HalHwiDefaultHandler;
|
||||
#endif
|
||||
}
|
||||
|
||||
val = OS_INT_IRQ_ENABLE | OS_INT_FIQ_ENABLE;
|
||||
READ_UINT32(reg, OS_INT_GLOBAL_ENABLE_ADDR);
|
||||
reg |= val;
|
||||
WRITE_UINT32(reg, OS_INT_GLOBAL_ENABLE_ADDR);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
UINT32 HalIntLock(VOID)
|
||||
{
|
||||
UINT32 ret;
|
||||
UINT32 temp;
|
||||
|
||||
__asm__ __volatile__("MRS %0, CPSR\n"
|
||||
"ORR %1, %0, #0xC0\n"
|
||||
"MSR CPSR_c, %1"
|
||||
: "=r"(ret), "=r"(temp)
|
||||
:
|
||||
: "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
VOID HalIntRestore(UINT32 intSave)
|
||||
{
|
||||
__asm__ __volatile__("MSR CPSR_c, %0" : : "r"(intSave));
|
||||
}
|
||||
|
||||
UINT32 HalIntUnLock(VOID)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
__asm__ __volatile__("MRS %0, CPSR\n"
|
||||
"BIC %0, %0, #0xC0\n"
|
||||
"MSR CPSR_c, %0"
|
||||
: "=r"(intSave)
|
||||
:
|
||||
: "memory");
|
||||
return intSave;
|
||||
}
|
||||
|
||||
150
kernel/arch/arm/arm9/gcc/los_timer.c
Normal file
150
kernel/arch/arm/arm9/gcc/los_timer.c
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_config.h"
|
||||
#include "los_sched.h"
|
||||
#include "los_arch_context.h"
|
||||
#include "los_arch_interrupt.h"
|
||||
#include "los_reg.h"
|
||||
|
||||
#define OS_TIMER_CLKDIV_POS 3
|
||||
#define OS_TIMER_CLKDIV_MASK 7
|
||||
#define OS_TIMER_INT_POS 7
|
||||
#define OS_TIMER_INT_MASK 7
|
||||
#define OS_TIMER_IRQ_NUM 8
|
||||
#define OS_TIMER_ENABLE (1U << 0)
|
||||
#define OS_TIMER_32K_CLK_BIT (1U << 21)
|
||||
#define OS_TIMER_CNT_READ_BIT (1U << 0)
|
||||
|
||||
#define OS_TIMER_REG_BASE 0x00802A40UL
|
||||
#define OS_TIMER_CLK_PWD_ADDR 0x00802008UL
|
||||
#define OS_TIMER_PERIOD_REG_ADDR (OS_TIMER_REG_BASE)
|
||||
#define OS_TIMER_CTL_REG_ADDR (OS_TIMER_REG_BASE + 12)
|
||||
#define OS_TIMER_READ_CTL_ADDR (OS_TIMER_REG_BASE + 16)
|
||||
#define OS_TIMER_READ_VAL_ADDR (OS_TIMER_REG_BASE + 20)
|
||||
|
||||
/* ****************************************************************************
|
||||
Function : HalTickStart
|
||||
Description : Configure Tick Interrupt Start
|
||||
Input : none
|
||||
output : none
|
||||
return : LOS_OK - Success , or LOS_ERRNO_TICK_CFG_INVALID - failed
|
||||
**************************************************************************** */
|
||||
WEAK UINT32 HalTickStart(OS_TICK_HANDLER handler)
|
||||
{
|
||||
UINT32 intSave = LOS_IntLock();
|
||||
UINT32 value;
|
||||
|
||||
READ_UINT32(value, OS_TIMER_CLK_PWD_ADDR);
|
||||
value &= ~(OS_TIMER_32K_CLK_BIT);
|
||||
WRITE_UINT32(value, OS_TIMER_CLK_PWD_ADDR);
|
||||
|
||||
value = LOSCFG_BASE_CORE_TICK_RESPONSE_MAX;
|
||||
WRITE_UINT32(value, OS_TIMER_PERIOD_REG_ADDR);
|
||||
|
||||
READ_UINT32(value, OS_TIMER_CTL_REG_ADDR);
|
||||
value &= ~(OS_TIMER_CLKDIV_MASK << OS_TIMER_CLKDIV_POS); // The default is 1, and the clock does not divide.
|
||||
value &= ~(OS_TIMER_INT_MASK << OS_TIMER_INT_POS); // Clearing interruption.
|
||||
value |= 0x1 << OS_TIMER_INT_POS;
|
||||
value |= OS_TIMER_ENABLE; // Enable timer.
|
||||
WRITE_UINT32(value, OS_TIMER_CTL_REG_ADDR);
|
||||
|
||||
(VOID)HalHwiCreate(OS_TIMER_IRQ_NUM, 0, 0, (HWI_PROC_FUNC)handler, 0);
|
||||
LOS_IntRestore(intSave);
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC VOID HalClockIrqClear(VOID)
|
||||
{
|
||||
UINT32 mask = OS_TIMER_INT_MASK << OS_TIMER_INT_POS;
|
||||
UINT32 status;
|
||||
|
||||
do {
|
||||
WRITE_UINT32(mask, OS_TIMER_CTL_REG_ADDR);
|
||||
READ_UINT32(status, OS_TIMER_CTL_REG_ADDR);
|
||||
} while (status & mask);
|
||||
}
|
||||
|
||||
WEAK VOID HalSysTickReload(UINT64 nextResponseTime)
|
||||
{
|
||||
HalTickLock();
|
||||
WRITE_UINT32(nextResponseTime, OS_TIMER_PERIOD_REG_ADDR);
|
||||
HalClockIrqClear();
|
||||
HalTickUnlock();
|
||||
}
|
||||
|
||||
WEAK UINT64 HalGetTickCycle(UINT32 *period)
|
||||
{
|
||||
UINT32 val;
|
||||
|
||||
READ_UINT32(*period, OS_TIMER_PERIOD_REG_ADDR);
|
||||
|
||||
WRITE_UINT32(OS_TIMER_CNT_READ_BIT, OS_TIMER_READ_CTL_ADDR);
|
||||
do {
|
||||
READ_UINT32(val, OS_TIMER_READ_CTL_ADDR);
|
||||
} while (val & OS_TIMER_CNT_READ_BIT); // Wait for the setting to take effect.
|
||||
|
||||
READ_UINT32(val, OS_TIMER_READ_VAL_ADDR);
|
||||
|
||||
return (UINT64)val;
|
||||
}
|
||||
|
||||
WEAK VOID HalTickLock(VOID)
|
||||
{
|
||||
UINT32 value;
|
||||
|
||||
READ_UINT32(value, OS_TIMER_CTL_REG_ADDR);
|
||||
value &= ~OS_TIMER_ENABLE;
|
||||
value &= ~(OS_TIMER_INT_MASK << OS_TIMER_INT_POS);
|
||||
value |= 0x1 << OS_TIMER_INT_POS;
|
||||
WRITE_UINT32(value, OS_TIMER_CTL_REG_ADDR);
|
||||
}
|
||||
|
||||
WEAK VOID HalTickUnlock(VOID)
|
||||
{
|
||||
UINT32 value;
|
||||
|
||||
READ_UINT32(value, OS_TIMER_CTL_REG_ADDR);
|
||||
value |= OS_TIMER_ENABLE;
|
||||
value &= ~(OS_TIMER_INT_MASK << OS_TIMER_INT_POS);
|
||||
value |= 0x1 << OS_TIMER_INT_POS;
|
||||
WRITE_UINT32(value, OS_TIMER_CTL_REG_ADDR);
|
||||
}
|
||||
|
||||
UINT32 HalEnterSleep(VOID)
|
||||
{
|
||||
dsb();
|
||||
wfi();
|
||||
isb();
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
149
kernel/arch/arm/arm9/gcc/reset_vector.S
Normal file
149
kernel/arch/arm/arm9/gcc/reset_vector.S
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
.equ CPSR_IRQ_DISABLE, 0x80
|
||||
.equ CPSR_FIQ_DISABLE, 0x40
|
||||
.equ CPSR_THUMB_ENABLE, 0x20
|
||||
.equ CPSR_USER_MODE, 0x10
|
||||
.equ CPSR_FIQ_MODE, 0x11
|
||||
.equ CPSR_IRQ_MODE, 0x12
|
||||
.equ CPSR_SVC_MODE, 0x13
|
||||
.equ CPSR_ABT_MODE, 0x17
|
||||
.equ CPSR_UNDEF_MODE, 0x1B
|
||||
|
||||
.global __exc_stack_top
|
||||
.global __irq_stack_top
|
||||
.global __fiq_stack_top
|
||||
.global __svc_stack_top
|
||||
.global __abt_stack_top
|
||||
.global __undef_stack_top
|
||||
.global __exc_stack
|
||||
.global __irq_stack
|
||||
.global __fiq_stack
|
||||
.global __svc_stack
|
||||
.global __abt_stack
|
||||
.global __undef_stack
|
||||
.global main
|
||||
|
||||
.extern HalExceptFiqHdl
|
||||
.extern HalExceptAddrAbortHdl
|
||||
.extern HalExceptDataAbortHdl
|
||||
.extern HalExceptPrefetchAbortHdl
|
||||
.extern HalExceptSwiHdl
|
||||
.extern HalExceptUndefInstrHdl
|
||||
.extern HalExceptIrqHdl
|
||||
.extern _bss_start
|
||||
.extern _bss_end
|
||||
|
||||
.code 32
|
||||
.text
|
||||
|
||||
.section ".vectors", "ax"
|
||||
.global _vector_start
|
||||
|
||||
_vector_start:
|
||||
B HalResetVector
|
||||
B HalExceptUndefInstrHdl
|
||||
B HalExceptSwiHdl
|
||||
B HalExceptPrefetchAbortHdl
|
||||
B HalExceptDataAbortHdl
|
||||
B HalExceptAddrAbortHdl
|
||||
B HalExceptIrqHdl
|
||||
B HalExceptFiqHdl
|
||||
|
||||
.globl HalResetVector
|
||||
.section ".boot", "ax"
|
||||
|
||||
HalResetVector:
|
||||
MOV R0, #(CPSR_IRQ_DISABLE | CPSR_FIQ_DISABLE | CPSR_IRQ_MODE)
|
||||
MSR CPSR, R0
|
||||
LDR SP, =__irq_stack_top
|
||||
|
||||
MOV R0, #(CPSR_IRQ_DISABLE | CPSR_FIQ_DISABLE | CPSR_UNDEF_MODE)
|
||||
MSR CPSR, R0
|
||||
LDR SP, =__undef_stack_top
|
||||
|
||||
MOV R0, #(CPSR_IRQ_DISABLE | CPSR_FIQ_DISABLE | CPSR_ABT_MODE)
|
||||
MSR CPSR, R0
|
||||
LDR SP, =__abt_stack_top
|
||||
|
||||
MOV R0, #(CPSR_IRQ_DISABLE | CPSR_FIQ_DISABLE | CPSR_FIQ_MODE)
|
||||
MSR CPSR, R0
|
||||
LDR SP, =__fiq_stack_top
|
||||
|
||||
MOV R0, #(CPSR_IRQ_DISABLE | CPSR_FIQ_DISABLE | CPSR_SVC_MODE)
|
||||
MSR CPSR, R0
|
||||
MSR SPSR, R0
|
||||
LDR SP, =__svc_stack_top
|
||||
|
||||
BL OsBssInit
|
||||
|
||||
B main
|
||||
B .
|
||||
|
||||
OsBssInit:
|
||||
LDR R0, =_bss_start
|
||||
LDR R1, =_bss_end
|
||||
|
||||
MOV R3, R1
|
||||
MOV R4, R0
|
||||
MOV R2, #0
|
||||
1: CMP R4, R3
|
||||
STRLO R2, [R4], #4
|
||||
BLO 1b
|
||||
BX LR
|
||||
|
||||
.section ".bss", "wa", %nobits
|
||||
.align 3
|
||||
__undef_stack:
|
||||
.space 32
|
||||
__undef_stack_top:
|
||||
|
||||
__abt_stack:
|
||||
.space 32
|
||||
__abt_stack_top:
|
||||
|
||||
__irq_stack:
|
||||
.space 1024
|
||||
__irq_stack_top:
|
||||
|
||||
__fiq_stack:
|
||||
.space 1024
|
||||
__fiq_stack_top:
|
||||
|
||||
__svc_stack:
|
||||
.space 1024
|
||||
__svc_stack_top:
|
||||
|
||||
__exc_stack:
|
||||
.space 512
|
||||
__exc_stack_top:
|
||||
|
||||
@@ -521,25 +521,6 @@ typedef struct TagExcContext {
|
||||
typedef VOID (*EXC_PROC_FUNC)(UINT32, EXC_CONTEXT_S *);
|
||||
VOID HalExcHandleEntry(UINT32 excType, UINT32 faultAddr, UINT32 pid, EXC_CONTEXT_S *excBufAddr);
|
||||
|
||||
/**
|
||||
* @ingroup los_arch_interrupt
|
||||
* @brief: Exception initialization.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to configure the exception function vector table.
|
||||
*
|
||||
* @attention:
|
||||
* <ul><li>None.</li></ul>
|
||||
*
|
||||
* @param uwArraySize [IN] Memory size of exception.
|
||||
*
|
||||
* @retval: None
|
||||
* @par Dependency:
|
||||
* <ul><li>los_arch_interrupt.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see None.
|
||||
*/
|
||||
VOID OsExcInit(VOID);
|
||||
|
||||
VOID HalExcNMI(VOID);
|
||||
VOID HalExcHardFault(VOID);
|
||||
VOID HalExcMemFault(VOID);
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "los_sched.h"
|
||||
#include "los_interrupt.h"
|
||||
#include "los_arch_timer.h"
|
||||
#include "los_debug.h"
|
||||
|
||||
/* ****************************************************************************
|
||||
Function : HalArchInit
|
||||
@@ -46,9 +47,15 @@
|
||||
Output : None
|
||||
Return : None
|
||||
**************************************************************************** */
|
||||
LITE_OS_SEC_TEXT_INIT VOID HalArchInit()
|
||||
LITE_OS_SEC_TEXT_INIT VOID HalArchInit(VOID)
|
||||
{
|
||||
UINT32 ret;
|
||||
HalHwiInit();
|
||||
|
||||
ret = HalTickStart(OsTickHandler);
|
||||
if (ret != LOS_OK) {
|
||||
PRINT_ERR("Tick start failed!\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* ****************************************************************************
|
||||
@@ -147,13 +154,9 @@ LITE_OS_SEC_TEXT_INIT VOID *HalTskStackInit(UINT32 taskID, UINT32 stackSize, VOI
|
||||
return (VOID *)context;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 HalStartSchedule(OS_TICK_HANDLER handler)
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 HalStartSchedule(VOID)
|
||||
{
|
||||
(VOID)LOS_IntLock();
|
||||
UINT32 ret = HalTickStart(handler);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
OsSchedStart();
|
||||
HalStartToRun();
|
||||
return LOS_OK; /* never return */
|
||||
|
||||
@@ -195,10 +195,10 @@ _hwiActiveCheck
|
||||
RBIT R2, R3
|
||||
CLZ R2, R2
|
||||
AND R12, R12, #1
|
||||
ADD R2, R2, R12, LSL #5 ; calculate R2 (hwi number) as uwPid
|
||||
ADD R2, R2, R12, LSL #5 ; calculate R2 (hwi number) as pid
|
||||
|
||||
_ExcInMSP
|
||||
CMP LR, #0XFFFFFFED
|
||||
CMP LR, #0xFFFFFFE9
|
||||
BNE _NoFloatInMsp
|
||||
ADD R3, R13, #104
|
||||
PUSH {R3}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user