import RT-Thread@9217865c without bsp, libcpu and components/net
This commit is contained in:
commit
e2376a3709
1414 changed files with 390370 additions and 0 deletions
46
.devcontainer/Dockerfile
Normal file
46
.devcontainer/Dockerfile
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
FROM ubuntu:20.04
|
||||||
|
|
||||||
|
ARG DEST_DIR=/root
|
||||||
|
|
||||||
|
WORKDIR ${DEST_DIR}
|
||||||
|
|
||||||
|
#system
|
||||||
|
RUN apt-get update
|
||||||
|
|
||||||
|
RUN apt-get upgrade -y
|
||||||
|
|
||||||
|
RUN apt-get install -y vim git wget python3 python-is-python3 pip gcc-arm-none-eabi scons libncurses5-dev
|
||||||
|
|
||||||
|
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y qemu-system-arm
|
||||||
|
|
||||||
|
#env
|
||||||
|
RUN mkdir /root/.env
|
||||||
|
|
||||||
|
RUN mkdir /root/.env/tools
|
||||||
|
|
||||||
|
RUN mkdir /root/.env/packages
|
||||||
|
|
||||||
|
RUN mkdir /root/.env/packages/packages
|
||||||
|
|
||||||
|
RUN mkdir /root/.env/tools/scripts
|
||||||
|
|
||||||
|
RUN touch /root/.env/packages/Kconfig
|
||||||
|
|
||||||
|
RUN echo 'source "$PKGS_DIR/packages/Kconfig"' > /root/.env/packages/Kconfig
|
||||||
|
|
||||||
|
RUN git clone https://github.com/RT-Thread/env.git /root/.env/tools/scripts/
|
||||||
|
|
||||||
|
RUN git clone https://github.com/RT-Thread/packages.git /root/.env/packages/packages/
|
||||||
|
|
||||||
|
ENV PATH="/root/.env/tools/scripts:$PATH"
|
||||||
|
|
||||||
|
RUN pip install requests -qq
|
||||||
|
|
||||||
|
ENV RTT_EXEC_PATH=/usr/bin
|
||||||
|
|
||||||
|
ENV RTT_CC=gcc
|
||||||
|
|
||||||
|
WORKDIR /root
|
||||||
|
|
||||||
|
|
||||||
|
|
15
.devcontainer/devcontainer.json
Normal file
15
.devcontainer/devcontainer.json
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
||||||
|
// https://github.com/microsoft/vscode-dev-containers/tree/v0.183.0/containers/ubuntu
|
||||||
|
// How to use this container: https://club.rt-thread.org/ask/article/d25fb0a88165f166.html
|
||||||
|
{
|
||||||
|
"name": "RT-THREAD QEMU",
|
||||||
|
"build": {
|
||||||
|
"dockerfile": "Dockerfile"
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"terminal.integrated.defaultProfile.linux": "bash"
|
||||||
|
},
|
||||||
|
"extensions": [
|
||||||
|
"ms-vscode.cpptools"
|
||||||
|
]
|
||||||
|
}
|
47
.gitattributes
vendored
Executable file
47
.gitattributes
vendored
Executable file
|
@ -0,0 +1,47 @@
|
||||||
|
*.c linguist-language=C
|
||||||
|
*.C linguist-language=C
|
||||||
|
*.h linguist-language=C
|
||||||
|
*.H linguist-language=C
|
||||||
|
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
*.S text
|
||||||
|
*.asm text
|
||||||
|
*.c text
|
||||||
|
*.cc text
|
||||||
|
*.cpp text
|
||||||
|
*.cxx text
|
||||||
|
*.h text
|
||||||
|
*.htm text
|
||||||
|
*.html text
|
||||||
|
*.in text
|
||||||
|
*.ld text
|
||||||
|
*.m4 text
|
||||||
|
*.mak text
|
||||||
|
*.mk text
|
||||||
|
*.py text
|
||||||
|
*.rb text
|
||||||
|
*.s text
|
||||||
|
*.sct text
|
||||||
|
*.sh text
|
||||||
|
*.txt text
|
||||||
|
*.xml text
|
||||||
|
SConscript text
|
||||||
|
Makefile text
|
||||||
|
AUTHORS text
|
||||||
|
COPYING text
|
||||||
|
|
||||||
|
*.LZO -text
|
||||||
|
*.Opt -text
|
||||||
|
*.Uv2 -text
|
||||||
|
*.ewp -text
|
||||||
|
*.eww -text
|
||||||
|
*.vcproj -text
|
||||||
|
*.bat -text
|
||||||
|
*.dos -text
|
||||||
|
*.icf -text
|
||||||
|
*.inf -text
|
||||||
|
*.ini -text
|
||||||
|
*.sct -text
|
||||||
|
*.xsd -text
|
||||||
|
Jamfile -text
|
53
.gitignore
vendored
Normal file
53
.gitignore
vendored
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
*.pyc
|
||||||
|
*.map
|
||||||
|
*.dblite
|
||||||
|
*.elf
|
||||||
|
*.bin
|
||||||
|
*.hex
|
||||||
|
*.axf
|
||||||
|
*.exe
|
||||||
|
*.pdb
|
||||||
|
*.idb
|
||||||
|
*.ilk
|
||||||
|
*.old
|
||||||
|
*.crf
|
||||||
|
build
|
||||||
|
Debug
|
||||||
|
rtthread
|
||||||
|
settings
|
||||||
|
documentation/html
|
||||||
|
*~
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
*.bak
|
||||||
|
*.dep
|
||||||
|
*.lib
|
||||||
|
*.a
|
||||||
|
*.i
|
||||||
|
*.d
|
||||||
|
*.dfinish
|
||||||
|
*.su
|
||||||
|
#source insight 4 project files
|
||||||
|
*.si4project
|
||||||
|
tools/kconfig-frontends/kconfig-mconf
|
||||||
|
packages
|
||||||
|
dist
|
||||||
|
rt-studio-project
|
||||||
|
cconfig.h
|
||||||
|
GPUCache
|
||||||
|
|
||||||
|
#cscope files
|
||||||
|
cscope.*
|
||||||
|
ncscope.*
|
||||||
|
|
||||||
|
#ctag files
|
||||||
|
tags
|
||||||
|
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.code-workspace
|
||||||
|
*.eide.*
|
||||||
|
.history
|
||||||
|
CMakeLists.txt
|
||||||
|
cmake-build-debug
|
||||||
|
*.mk
|
70
.hooks/pre-commit
Normal file
70
.hooks/pre-commit
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# AUTHOR: supperthomas
|
||||||
|
|
||||||
|
if git rev-parse --verify HEAD >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
against=HEAD
|
||||||
|
else
|
||||||
|
# Initial commit: diff against an empty tree object
|
||||||
|
against=$(git hash-object -t tree /dev/null)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# We only filter the file name with c or cpp file.
|
||||||
|
changed_files=$(git diff-index --cached $against | \
|
||||||
|
grep -E '[MA] .*\.(c|cpp|cc|cxx)$' | cut -d' ' -f 2)
|
||||||
|
|
||||||
|
|
||||||
|
if which cppcheck > /dev/null; then
|
||||||
|
if [ -n "$changed_files" ]; then
|
||||||
|
cppcheck --enable=warning,performance,portability --inline-suppr --error-exitcode=1 --platform=win64 --force $changed_files
|
||||||
|
err=$?
|
||||||
|
if [ $err -ne 0 ]; then
|
||||||
|
echo "[rt-thread][cppcheck] we found a obvious fault, please fix the error then commit again"
|
||||||
|
exit $err
|
||||||
|
else
|
||||||
|
echo "[rt-thread][cppcheck] cppcheck ok."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "cppcheck does not exist"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# We only filter the file name with c or cpp or h file.
|
||||||
|
# astyle only astyle the added file[because of code reivewer], if you want change modify file, please use [MA]
|
||||||
|
changed_files=$(git diff-index --cached $against | \
|
||||||
|
grep -E '[MA] .*\.(c|cpp|h)$' | cut -d' ' -f 2)
|
||||||
|
|
||||||
|
if which astyle > /dev/null; then
|
||||||
|
if [ -n "$changed_files" ]; then
|
||||||
|
astyle --style=allman --indent=spaces=4 --indent=spaces=4 --indent=spaces=4 --pad-header --pad-header --pad-header --align-pointer=name --lineend=linux --convert-tabs --verbose $changed_files
|
||||||
|
err=$?
|
||||||
|
if [ $err -ne 0 ]; then
|
||||||
|
echo "[rt-thread][astyle] we found a obvious fault, please fix the error then commit again"
|
||||||
|
exit $err
|
||||||
|
else
|
||||||
|
echo "[rt-thread][astyle] astyle file ok"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "astyle does not exist"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# We only filter the file name with c or cpp file.
|
||||||
|
changed_files=$(git diff-index --cached $against | \
|
||||||
|
grep -E '[MA] .*\.(c|cpp|h)$' | cut -d' ' -f 2)
|
||||||
|
# formatting check
|
||||||
|
# https://github.com/mysterywolf/formatting
|
||||||
|
# formatting cmd ref https://github.com/supperthomas/git_auto_script
|
||||||
|
if which formatting > /dev/null; then
|
||||||
|
if [ -n "$changed_files" ]; then
|
||||||
|
formatting $changed_files
|
||||||
|
echo "[rt-thread] formatting $changed_files is ok"
|
||||||
|
git add $changed_files
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "formatting does not exist"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
15
.hooks/readme.md
Normal file
15
.hooks/readme.md
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# How to use git hook
|
||||||
|
|
||||||
|
## SDK install
|
||||||
|
|
||||||
|
Please use cmd `git config --local core.hooksPath .hooks` for git hooks local.
|
||||||
|
|
||||||
|
## git hooks使用注意事项
|
||||||
|
|
||||||
|
- hooks里面的要安装cppcheck和astyle以及formatting命令行才能使用,如果想要去掉某个选项,在pre-commit中注释掉相应的命令即可。
|
||||||
|
- 取消hook选项请使用命令`git config --unset --local core.hooksPath .hooks` 可以取消hook格式化文件
|
||||||
|
- 这个githook不敲命令是不生效的
|
||||||
|
- githook会用astyle格式化一些文件(这个按照rt-thread coding-style里面的设置来的),这里要注意,如果之前文件没有经过astlye格式化的话,会出现很多修改,如果修改过多,建议不用astyle进行格式化。
|
||||||
|
- formatting命令只针对`c|cpp|h` 文件,并没有针对文件夹修改等。所以如果有SDK等不希望formatting的文件,请先将hooks功能去掉,commit之后,再考虑使用hooks命令。
|
||||||
|
- 如果对git的pre-commit不是很熟悉,建议可以先不用这个hooks。
|
||||||
|
|
45
AUTHORS
Executable file
45
AUTHORS
Executable file
|
@ -0,0 +1,45 @@
|
||||||
|
Kernel Design & Implementation
|
||||||
|
- Bernard Xiong <bernard.xiong@gmail.com>
|
||||||
|
|
||||||
|
LwIP 1.3.0/1.3.1/1.3.2/1.4.0
|
||||||
|
- Porting
|
||||||
|
Qiu Yi
|
||||||
|
Mbbill
|
||||||
|
- Testing
|
||||||
|
Bernard Xiong
|
||||||
|
|
||||||
|
Filesystem
|
||||||
|
- Porting and Add Virtual Filesystem
|
||||||
|
- Testing
|
||||||
|
Qiu Yi
|
||||||
|
prife
|
||||||
|
|
||||||
|
RTGUI
|
||||||
|
- Design and Implemenation
|
||||||
|
Bernard Xiong
|
||||||
|
Grissiom
|
||||||
|
|
||||||
|
BSP
|
||||||
|
Bernard Xiong
|
||||||
|
- ATMEL AT91SAM7S64 & AT91SAM7X256 Porting
|
||||||
|
- STM32 Porting
|
||||||
|
- S3C4510 Porting
|
||||||
|
|
||||||
|
Mbbill
|
||||||
|
- ATMEL AT91SAM7X256
|
||||||
|
|
||||||
|
Xulong Cao
|
||||||
|
- QEMU/x86
|
||||||
|
|
||||||
|
Aozima
|
||||||
|
- LPC 2148 Porting
|
||||||
|
- STM32 Porting
|
||||||
|
|
||||||
|
Jing Lee
|
||||||
|
- LPC 2478 Porting
|
||||||
|
|
||||||
|
Qiu Yi
|
||||||
|
- S3C2410 & S3C2440 Porting
|
||||||
|
- TI LM3S
|
||||||
|
|
||||||
|
others...
|
2465
ChangeLog.md
Normal file
2465
ChangeLog.md
Normal file
File diff suppressed because it is too large
Load diff
154
Jenkinsfile
vendored
Normal file
154
Jenkinsfile
vendored
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
pipeline {
|
||||||
|
agent {
|
||||||
|
docker {
|
||||||
|
image 'ubuntu_ci:latest'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stages {
|
||||||
|
stage('build') {
|
||||||
|
steps {
|
||||||
|
sh '''
|
||||||
|
|
||||||
|
uname -a
|
||||||
|
cat /etc/issue
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y -qq lib32ncurses5 lib32z1 > /dev/null
|
||||||
|
|
||||||
|
curl -s http://download.isrc.rt-thread.com/download/gcc-arm-none-eabi-5_4-2016q3-20160926-linux.tar.bz2 | sudo tar xjf - -C /opt
|
||||||
|
/opt/gcc-arm-none-eabi-5_4-2016q3/bin/arm-none-eabi-gcc --version
|
||||||
|
'''
|
||||||
|
|
||||||
|
script {
|
||||||
|
def bsp_array = [
|
||||||
|
['CME_M7', 'sourcery-arm'],
|
||||||
|
// ['apollo2', 'sourcery-arm'], /* CI compile not support */
|
||||||
|
['asm9260t', 'sourcery-arm'],
|
||||||
|
['at91sam9260', 'sourcery-arm'],
|
||||||
|
['allwinner_tina', 'sourcery-arm'],
|
||||||
|
['efm32', 'sourcery-arm'],
|
||||||
|
// ['gd32e230k-start', 'sourcery-arm'], /* CI compile not support */
|
||||||
|
['gd32303e-eval', 'sourcery-arm'],
|
||||||
|
// ['gd32450z-eval', 'sourcery-arm'], /* CI link not support */
|
||||||
|
['imx6sx/cortex-a9', 'sourcery-arm'],
|
||||||
|
// ['imxrt/imxrt1052-atk-commander', 'sourcery-arm'], /* CI compile not support */
|
||||||
|
// ['imxrt/imxrt1052-fire-pro', 'sourcery-arm'], /* CI compile not support */
|
||||||
|
// ['imxrt/imxrt1052-nxp-evk', 'sourcery-arm'], /* CI compile not support */
|
||||||
|
['lm3s8962', 'sourcery-arm'],
|
||||||
|
['lm3s9b9x', 'sourcery-arm'],
|
||||||
|
['lm4f232', 'sourcery-arm'],
|
||||||
|
['tm4c129x', 'sourcery-arm'],
|
||||||
|
// ['lpc43xx/M4', 'sourcery-arm'], /* CI compile not support */
|
||||||
|
['lpc176x', 'sourcery-arm'],
|
||||||
|
['lpc178x', 'sourcery-arm'],
|
||||||
|
['lpc408x', 'sourcery-arm'],
|
||||||
|
['lpc1114', 'sourcery-arm'],
|
||||||
|
['lpc2148', 'sourcery-arm'],
|
||||||
|
['lpc2478', 'sourcery-arm'],
|
||||||
|
['lpc5410x', 'sourcery-arm'],
|
||||||
|
// ['lpc54114-lite', 'sourcery-arm'], /* CI link not support */
|
||||||
|
['mb9bf500r', 'sourcery-arm'],
|
||||||
|
['mb9bf506r', 'sourcery-arm'],
|
||||||
|
['mb9bf618s', 'sourcery-arm'],
|
||||||
|
['mb9bf568r', 'sourcery-arm'],
|
||||||
|
['mini2440', 'sourcery-arm'],
|
||||||
|
['nuvoton_nuc472', 'sourcery-arm'],
|
||||||
|
['nuvoton_m05x', 'sourcery-arm'],
|
||||||
|
['qemu-vexpress-a9', 'sourcery-arm'],
|
||||||
|
['qemu-vexpress-gemini', 'sourcery-arm'],
|
||||||
|
['sam7x', 'sourcery-arm'],
|
||||||
|
// ['stm32/stm32f072-st-nucleo', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f091-st-nucleo', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f103-atk-nano', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f103-atk-warshipv3', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f103-dofly-lyc8', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f103-dofly-M3S', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f103-fire-arbitrary', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f103-hw100k-ibox', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f103-mini-system', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f103-onenet-nbiot', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f103-yf-ufun', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f107-uc-eval', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f401-st-nucleo', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f405-smdz-breadfruit', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f407-atk-explorer', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f407-st-discovery', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f410-st-nucleo', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f411-st-nucleo', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f411-weact-MiniF4', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f413-st-nucleo', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f427-robomaster-a', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f429-armfly-v6', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f429-atk-apollo', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f429-fire-challenger', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f429-st-disco', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f446-st-nucleo', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f469-st-disco', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32f746-st-disco', 'sourcery-arm'], /* CI compile -mcpu= not support */
|
||||||
|
// ['stm32/stm32f767-atk-apollo', 'sourcery-arm'], /* CI compile -mcpu= not support */
|
||||||
|
// ['stm32/stm32f767-fire-challenger', 'sourcery-arm'], /* CI compile -mcpu= not support */
|
||||||
|
// ['stm32/stm32f767-st-nucleo', 'sourcery-arm'], /* CI compile -mcpu= not support */
|
||||||
|
// ['stm32/stm32g071-st-nucleo', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32g431-st-nucleo', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32h743-atk-apollo', 'sourcery-arm'], /* CI compile -mcpu= not support */
|
||||||
|
// ['stm32/stm32h743-st-nucleo', 'sourcery-arm'], /* CI compile -mcpu= not support */
|
||||||
|
// ['stm32/stm32h747-st-discovery', 'sourcery-arm'], /* CI compile -mcpu= not support */
|
||||||
|
// ['stm32/stm32l4r9-st-eval', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32l010-st-nucleo', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32l053-st-nucleo', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32l412-st-nucleo', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32l432-st-nucleo', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32l433-st-nucleo', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32l475-atk-pandora', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32l475-st-discovery', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32l476-st-nucleo', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32l496-ali-developer', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
// ['stm32/stm32l496-st-nucleo', 'sourcery-arm'], /* CI compile C99 not support */
|
||||||
|
['stm32f20x', 'sourcery-arm'],
|
||||||
|
['beaglebone', 'sourcery-arm'],
|
||||||
|
['frdm-k64f', 'sourcery-arm'],
|
||||||
|
['xplorer4330/M4', 'sourcery-arm'],
|
||||||
|
// ['at32/at32f403a-start', 'sourcery-arm'],/* CI link not support */
|
||||||
|
// ['at32/at32f407-start', 'sourcery-arm']/* CI compile C99 not support */
|
||||||
|
]
|
||||||
|
|
||||||
|
for (int i in bsp_array) {
|
||||||
|
|
||||||
|
sh """
|
||||||
|
|
||||||
|
export RTT_BSP=${i.getAt(0)}
|
||||||
|
export RTT_TOOL_CHAIN=${i.getAt(1)}
|
||||||
|
export RTT_EXEC_PATH=/opt/gcc-arm-none-eabi-5_4-2016q3/bin/
|
||||||
|
export RTT_CC='gcc'
|
||||||
|
export RTT_ROOT=`pwd`
|
||||||
|
|
||||||
|
echo \$RTT_EXEC_PATH
|
||||||
|
|
||||||
|
export CPUS=\$(cat /proc/cpuinfo | grep "processor" | sort | uniq | wc -l)
|
||||||
|
scons -j\${CPUS} -C bsp/\$RTT_BSP
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
post {
|
||||||
|
failure {
|
||||||
|
addGiteeMRComment(comment: """:x: Jenkins CI 构建失败。\n\n \
|
||||||
|
查看更多日志详细信息: \
|
||||||
|
<a href="${env.RUN_DISPLAY_URL}">Jenkins[${env.JOB_NAME} # ${env.BUILD_NUMBER}]</a> \
|
||||||
|
<hr /> \
|
||||||
|
:x: The Jenkins CI build failed.\n\n \
|
||||||
|
Results available at: \
|
||||||
|
<a href="${env.RUN_DISPLAY_URL}">Jenkins[${env.JOB_NAME} # ${env.BUILD_NUMBER}]</a>""")
|
||||||
|
}
|
||||||
|
success {
|
||||||
|
addGiteeMRComment(comment: """:white_check_mark: Jenkins CI 构建通过。\n\n \
|
||||||
|
查看更多日志详细信息: \
|
||||||
|
<a href="${env.RUN_DISPLAY_URL}">Jenkins[${env.JOB_NAME} # ${env.BUILD_NUMBER}]</a> \
|
||||||
|
<hr /> \
|
||||||
|
:white_check_mark: The Jenkins CI build passed.\n\n \
|
||||||
|
Results available at: \
|
||||||
|
<a href="${env.RUN_DISPLAY_URL}">Jenkins[${env.JOB_NAME} # ${env.BUILD_NUMBER}]</a>""")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
4
Kconfig
Normal file
4
Kconfig
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
source "$RTT_DIR/src/Kconfig"
|
||||||
|
source "$RTT_DIR/libcpu/Kconfig"
|
||||||
|
source "$RTT_DIR/components/Kconfig"
|
||||||
|
source "$RTT_DIR/examples/utest/testcases/Kconfig"
|
201
LICENSE
Normal file
201
LICENSE
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
147
README_de.md
Normal file
147
README_de.md
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
<p align="center">
|
||||||
|
<img src="documentation/figures/logo.png" width="60%" >
|
||||||
|
</p>
|
||||||
|
|
||||||
|
[English](README.md) | [中文](README_zh.md) | [Español](README_es.md) | **Deutsch**
|
||||||
|
|
||||||
|
[](https://github.com/RT-Thread/rt-thread/stargazers)
|
||||||
|
[](https://gitee.com/rtthread/rt-thread/stargazers)
|
||||||
|
[](https://github.com/RT-Thread/rt-thread/blob/master/LICENSE)
|
||||||
|
[](https://github.com/RT-Thread/rt-thread/releases)
|
||||||
|
[](https://gitter.im/RT-Thread/rt-thread?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
|
[](https://github.com/RT-Thread/rt-thread/pulls)
|
||||||
|
[](https://github.com/RT-Thread/rt-thread/pulls)
|
||||||
|
|
||||||
|
# RT-Thread
|
||||||
|
|
||||||
|
RT-Thread wurde 2006 geboren und ist ein quelloffenes, neutrales und gemeinschaftsbasiertes Echtzeitbetriebssystem (RTOS).
|
||||||
|
|
||||||
|
RT-Thread ist hauptsächlich in der Sprache C geschrieben, leicht zu verstehen und einfach zu portieren (kann schnell auf eine breite Palette von Mainstream-MCUs und Modul-Chips portiert werden). Es wendet objektorientierte Programmiermethoden auf das Design von Echtzeitsystemen an, wodurch der Code elegant, strukturiert, modular und sehr anpassbar ist.
|
||||||
|
|
||||||
|
RT-Thread gibt es in einer Standard- und einer Nano-Version. Für ressourcenbeschränkte Mikrocontroller (MCU)-Systeme kann die Nano-Version, die nur 3KB Flash- und 1,2KB RAM-Speicherressourcen benötigt, mit einfach zu bedienenden Tools angepasst werden. Für ressourcenreiche IoT-Geräte kann RT-Thread das Online-Tool zur Verwaltung von Softwarepaketen zusammen mit Systemkonfigurationswerkzeugen verwenden, um einen intuitiven und schnellen modularen Zuschnitt zu erreichen und umfangreiche Softwarepakete nahtlos zu importieren.
|
||||||
|
|
||||||
|
RT-Thread-Architektur
|
||||||
|
|
||||||
|
RT-Thread verfügt nicht nur über einen Echtzeit-Kernel, sondern auch über umfangreiche Komponenten. Seine Architektur ist wie folgt:
|
||||||
|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
Sie umfasst:
|
||||||
|
|
||||||
|
- Kernel-Schicht: RT-Thread-Kernel, das Kernstück von RT-Thread, umfasst die Implementierung von Objekten im Kernel-System, wie z. B. Multi-Threading und dessen Scheduling, Semaphor, Mailbox, Nachrichtenwarteschlange, Speicherverwaltung, Timer usw.; libcpu/BSP (Chip Migration Related Files/Board Support Package) ist eng mit der Hardware verbunden und besteht aus Peripherie-Treibern und CPU-Portierung.
|
||||||
|
|
||||||
|
- Komponenten und Dienstebene: Die Komponenten basieren auf Software der oberen Ebene des RT-Thread-Kernels, wie z. B. virtuelle Dateisysteme, FinSH-Befehlszeilenschnittstellen, Netzwerk-Frameworks, Geräte-Frameworks und mehr. Der modulare Aufbau ermöglicht eine hohe interne Kohäsion innerhalb der Komponenten und eine geringe Kopplung zwischen den Komponenten.
|
||||||
|
|
||||||
|
- [RT-Thread-Softwarepaket](https://packages.rt-thread.org/en/index.html): Eine Allzweck-Softwarekomponente, die auf der IoT-Betriebssystemplattform RT-Thread für verschiedene Anwendungsbereiche läuft und aus Beschreibungsinformationen, Quellcode oder Bibliotheksdateien besteht. RT-Thread bietet eine offene Paketplattform mit offiziell verfügbaren oder von Entwicklern bereitgestellten Paketen, die Entwicklern eine Auswahl an wiederverwendbaren Paketen bieten, die ein wichtiger Teil des RT-Thread-Ökosystems sind. Das Paket-Ökosystem ist für die Wahl eines Betriebssystems von entscheidender Bedeutung, da diese Pakete in hohem Maße wiederverwendbar und modular sind, was es den Anwendungsentwicklern erleichtert, das gewünschte System in kürzester Zeit zu erstellen. RT-Thread unterstützt mehr als 370 Softwarepakete.
|
||||||
|
|
||||||
|
## RT-Thread Merkmale
|
||||||
|
|
||||||
|
- Der minimale Kernel wurde für Geräte mit begrenzten Ressourcen entwickelt und benötigt nur 1,2 KB RAM und 3 KB Flash.
|
||||||
|
- Eine Vielzahl von Standardschnittstellen, wie POSIX, CMSIS, C++ Anwendungsumgebung.
|
||||||
|
- Verfügt über zahlreiche Komponenten und ein florierendes und schnell wachsendes Paket-Ökosystem.
|
||||||
|
- Eleganter Codestil, einfach zu verwenden, zu lesen und zu beherrschen.
|
||||||
|
- Hohe Skalierbarkeit. RT-Thread hat eine hochwertige skalierbare Software-Architektur, lose Kopplung, Modularität, ist leicht anzupassen und zu erweitern.
|
||||||
|
- Unterstützt Hochleistungsanwendungen.
|
||||||
|
- Unterstützt alle gängigen Kompilierwerkzeuge wie GCC, Keil und IAR.
|
||||||
|
- Unterstützt eine breite Palette von <a href="https://www.rt-thread.io/board.html">architekturen und chips</a>.
|
||||||
|
|
||||||
|
## Code-Katalog
|
||||||
|
|
||||||
|
Der RT-Thread-Quellcodekatalog wird wie folgt dargestellt:
|
||||||
|
|
||||||
|
| Name | Beschreibung |
|
||||||
|
| ------------- | ------------------------------------------------------- |
|
||||||
|
| BSP | Board Support Package basierend auf der Portierung von verschiedenen Entwicklungsboards. |
|
||||||
|
| Komponenten | Komponenten, wie Shell, Dateisystem, Protokollstapel usw. |
|
||||||
|
| Dokumentation | Verwandte Dokumente, wie Coding Style, Doxygen usw. |
|
||||||
|
| Beispiele | Zugehöriger Beispielcode. |
|
||||||
|
| einschließen | Kopfdateien des RT-Thread-Kernels. |
|
||||||
|
| libcpu | CPU-Portierungscode wie ARM/MIPS/RISC-V usw. |
|
||||||
|
| src | Die Quelldateien für den RT-Thread-Kernel. |
|
||||||
|
| Werkzeuge | Die Skriptdateien für das RT-Thread Befehlserstellungswerkzeug. |
|
||||||
|
|
||||||
|
RT-Thread wurde inzwischen für fast 200 Entwicklungsboards portiert, die meisten BSPs unterstützen MDK, IAR-Entwicklungsumgebung und GCC-Compiler und bieten ein Standard-MDK- und IAR-Projekt, das es den Benutzern ermöglicht, ihren eigenen Anwendungscode direkt auf der Grundlage des Projekts hinzuzufügen. Jedes BSP hat eine ähnliche Verzeichnisstruktur, und die meisten BSPs bieten eine README.md-Datei, eine Datei im Markdown-Format, die eine grundlegende Einführung in das BSP enthält und erklärt, wie man einfach mit dem BSP beginnt.
|
||||||
|
|
||||||
|
# Ressourcen
|
||||||
|
|
||||||
|
## Unterstützte Architekturen
|
||||||
|
|
||||||
|
RT-Thread unterstützt viele Architekturen und hat die wichtigsten Architekturen in aktuellen Anwendungen abgedeckt. Architektur und beteiligter Chip-Hersteller:
|
||||||
|
|
||||||
|
- **ARM Cortex-M0/M0+**:manufacturers like ST
|
||||||
|
- **ARM Cortex-M3**:manufacturers like ST、Winner Micro、MindMotion, ect.
|
||||||
|
- **ARM Cortex-M4**:manufacturers like ST、Infineon、Nuvoton、NXP、[Nordic](https://github.com/RT-Thread/rt-thread/tree/master/bsp/nrf5x)、GigaDevice、Realtek、Ambiq Micro, ect.
|
||||||
|
- **ARM Cortex-M7**:manufacturers like ST、NXP
|
||||||
|
- **ARM Cortex-M23**:manufacturers like GigaDevice
|
||||||
|
- **ARM Cortex-M33**:manufacturers like ST
|
||||||
|
- **ARM Cortex-R4**
|
||||||
|
- **ARM Cortex-A8/A9**:manufacturers like NXP
|
||||||
|
- **ARM7**:manufacturers like Samsung
|
||||||
|
- **ARM9**:manufacturers like Allwinner、Xilinx 、GOKE
|
||||||
|
- **ARM11**:manufacturers like Fullhan
|
||||||
|
- **MIPS32**:manufacturers like loongson、Ingenic
|
||||||
|
- **RISC-V RV32E/RV32I[F]/RV64[D]**:manufacturers like Hifive、[Kendryte](https://github.com/RT-Thread/rt-thread/tree/master/bsp/k210)、[bouffalo_lab](https://github.com/RT-Thread/rt-thread/tree/master/bsp/bouffalo_lab)、[Nuclei](https://nucleisys.com/)、[T-Head](https://www.t-head.cn/)、[HPMicro](https://github.com/RT-Thread/rt-thread/tree/master/bsp/hpmicro)
|
||||||
|
- **ARC**:manufacturers like SYNOPSYS
|
||||||
|
- **DSP**:manufacturers like TI
|
||||||
|
- **C-Sky**
|
||||||
|
- **x86**
|
||||||
|
|
||||||
|
## Unterstützte IDE und Compiler
|
||||||
|
|
||||||
|
Die wichtigsten von RT-Thread unterstützten IDEs/Compiler sind:
|
||||||
|
|
||||||
|
- RT-Thread Studio IDE
|
||||||
|
- MDK KEIL
|
||||||
|
- IAR
|
||||||
|
- GCC
|
||||||
|
|
||||||
|
## RT-Thread Studio IDE
|
||||||
|
|
||||||
|
[User Manual](https://www.rt-thread.io/document/site/rtthread-studio/um/studio-user-manual/) | [Tutorial Videos](https://youtu.be/ucq5eJgZIQg)
|
||||||
|
|
||||||
|
RT-Thread Studio IDE (auch bekannt als RT-Studio) ist eine integrierte Entwicklungsumgebung aus einer Hand, die vom RT-Thread-Team entwickelt wurde. Es verfügt über ein einfach zu bedienendes grafisches Konfigurationssystem und eine Fülle von Software-Paketen und Komponenten Ressourcen. RT-Studio verfügt über Funktionen zur Projekterstellung, -konfiguration und -verwaltung sowie zur Code-Bearbeitung, SDK-Verwaltung, Build-Konfiguration, Debugging-Konfiguration, Programm-Download und Debugging. Wir sind bestrebt, die Nutzung von RT-Studio so intuitiv wie möglich zu gestalten, Doppelarbeit zu reduzieren und die Effizienz der Entwicklung zu verbessern.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Env-Werkzeug
|
||||||
|
|
||||||
|
[User Manual](documentation/env/env.md) | [Tutorial Videos](https://www.youtube.com/watch?v=dEK94o_YoSo)
|
||||||
|
|
||||||
|
In der Anfangsphase schuf das RT-Thread-Team auch ein Hilfswerkzeug namens Env. Dabei handelt es sich um ein Hilfstool mit einer TUI (textbasierten Benutzeroberfläche). Entwickler können das Env-Tool verwenden, um GCC, Keil MDK und IAR-Projekte zu konfigurieren und zu generieren.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
# Erste Schritte
|
||||||
|
|
||||||
|
[RT-Thread Programmierhandbuch](https://www.rt-thread.io/document/site/tutorial/quick-start/introduction/introduction/) | [RT-Thread Studio IDE](https://www.rt-thread.io/studio.html) | [Kernel Sample](https://github.com/RT-Thread-packages/kernel-sample) | [RT-Thread Einsteigerhandbuch](https://www.youtube.com/watch?v=ZMi1O-Rr7yc&list=PLXUV89C_M3G5KVw2IerI-pqApdSM_IaZo)
|
||||||
|
|
||||||
|
Basierend auf [STM32F103 BluePill](https://github.com/RT-Thread/rt-thread/tree/master/bsp/stm32/stm32f103-blue-pill) | [Raspberry Pi Pico](https://github.com/RT-Thread/rt-thread/tree/master/bsp/raspberry-pico)
|
||||||
|
|
||||||
|
## Simulator
|
||||||
|
|
||||||
|
Das RT-Thread BSP kann direkt kompiliert und zur Verwendung auf das entsprechende Entwicklungsboard heruntergeladen werden. Darüber hinaus bietet RT-Thread auch das qemu-vexpress-a9 BSP, das ohne Hardware-Plattform verwendet werden kann. Weitere Informationen finden Sie in der Anleitung für die ersten Schritte unten.
|
||||||
|
[Windows](documentation/quick-start/quick_start_qemu/quick_start_qemu.md) | [Linux Ubuntu](documentation/quick-start/quick_start_qemu/quick_start_qemu_linux.md) | [Mac OS](documentation/quick-start/quick_start_qemu/quick_start_qemu_macos.md)
|
||||||
|
|
||||||
|
# Lizenz
|
||||||
|
|
||||||
|
RT-Thread ist eine Open-Source-Software und steht seit v3.1.1 unter der Apache License Version 2.0. Lizenzinformationen und Copyright-Informationen sind in der Regel am Anfang des Codes zu finden:
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
* ...
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
# Gemeinschaft
|
||||||
|
|
||||||
|
RT-Thread ist sehr dankbar für die Unterstützung durch alle Entwickler der Community. Wenn Sie Ideen, Vorschläge oder Fragen zur Verwendung von RT-Thread haben, können Sie RT-Thread über die folgenden Kanäle erreichen, und wir aktualisieren RT-Thread auch in Echtzeit über diese Kanäle. Gleichzeitig können alle Fragen im [Issue-Bereich des RT-Thread-Repositorys](https://github.com/RT-Thread/rt-thread/issues) oder im [RT-Thread-Forum](https://club.rt-thread.io/), gestellt werden, und die Community-Mitglieder werden sie beantworten.
|
||||||
|
|
||||||
|
[Website](https://www.rt-thread.io) | [Github](https://github.com/RT-Thread/rt-thread) | [Twitter](https://twitter.com/rt_thread) | [LinkedIn](https://www.linkedin.com/company/rt-thread-iot-os/posts/?feedView=all) | [Youtube](https://www.youtube.com/channel/UCdDHtIfSYPq4002r27ffqPw) | [Facebook](https://www.facebook.com/RT-Thread-IoT-OS-110395723808463/?modal=admin_todo_tour) | [Medium](https://rt-thread.medium.com/)
|
||||||
|
|
||||||
|
# Beitrag
|
||||||
|
|
||||||
|
Wenn Sie an RT-Thread interessiert sind und sich an der Entwicklung von RT-Thread beteiligen und einen Beitrag zum Code leisten wollen, lesen Sie bitte den [Code Contribution Guide](documentation/contribution_guide/contribution_guide.md).
|
146
README_es.md
Normal file
146
README_es.md
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
<p align="center">
|
||||||
|
<img src="documentation/figures/logo.png" width="60%" >
|
||||||
|
</p>
|
||||||
|
|
||||||
|
[English](README.md) | [中文](README_zh.md) | **Español** | [Deutsch](README_de.md)
|
||||||
|
|
||||||
|
[](https://github.com/RT-Thread/rt-thread/stargazers)
|
||||||
|
[](https://gitee.com/rtthread/rt-thread/stargazers)
|
||||||
|
[](https://github.com/RT-Thread/rt-thread/blob/master/LICENSE)
|
||||||
|
[](https://github.com/RT-Thread/rt-thread/releases)
|
||||||
|
[](https://gitter.im/RT-Thread/rt-thread?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
|
[](https://github.com/RT-Thread/rt-thread/pulls)
|
||||||
|
[](https://github.com/RT-Thread/rt-thread/pulls)
|
||||||
|
|
||||||
|
# RT-Thread
|
||||||
|
|
||||||
|
RT-Thread nació en 2006, es un sistema operativo en tiempo real (RTOS) de código abierto, neutral y basado en la comunidad.
|
||||||
|
|
||||||
|
RT-Thread está escrito principalmente en lenguaje C, fácil de entender y fácil de portar (puede ser rápidamente portado a una amplia gama de MCUs y chips de módulos). Aplica métodos de programación orientados a objetos al diseño de sistemas en tiempo real, lo que hace que el código sea elegante, estructurado, modular y muy adaptable.
|
||||||
|
|
||||||
|
RT-Thread tiene una versión estándar y una versión Nano. Para los sistemas de microcontroladores (MCU) con recursos limitados, la versión Nano, que requiere solo 3KB de memoria Flash y 1,2KB de memoria RAM, puede adaptarse con herramientas fáciles de usar. Para los dispositivos IoT con muchos recursos, RT-Thread puede utilizar la herramienta de gestión de paquetes de software en línea, junto con las herramientas de configuración del sistema, para lograr un corte modular intuitivo y rápido, importando sin problemas paquetes de software ricos; así, logrando funciones complejas como la interfaz gráfica de Android y efectos de deslizamiento táctil, efectos de interacción de voz inteligente, etc.
|
||||||
|
|
||||||
|
## Arquitectura RT-Thread
|
||||||
|
|
||||||
|
RT-Thread no sólo dispone de un núcleo en tiempo real, sino también de ricos componentes. Su arquitectura es la siguiente:
|
||||||
|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
Incluye:
|
||||||
|
|
||||||
|
- Capa del kernel: El kernel de RT-Thread, la parte central de RT-Thread, incluye la implementación de objetos en el sistema del kernel, como el multihilo y su programación, el semáforo, el buzón, la cola de mensajes, la gestión de la memoria, el temporizador, etc.; libcpu/BSP (Chip Migration Related Files/Board Support Package) está estrechamente relacionado con el hardware y consiste en controladores periféricos y portación de la CPU
|
||||||
|
|
||||||
|
- Componentes y capa de servicios: Los componentes se basan en software de nivel superior sobre el núcleo de RT-Thread, como sistemas de archivos virtuales, interfaces de línea de comandos FinSH, frameworks de red, frameworks de dispositivos, etc. Su diseño modular permite una alta cohesión interna dentro de los componentes y un bajo acoplamiento entre ellos.
|
||||||
|
|
||||||
|
- [Paquete de software RT-Thread](https://packages.rt-thread.org/en/index.html): Un componente de software de propósito general que se ejecuta en la plataforma del sistema operativo RT-Thread IoT para diferentes áreas de aplicación, que consiste en información de descripción, código fuente o archivos de biblioteca. RT-Thread proporciona una plataforma de paquetes abierta con paquetes disponibles oficialmente o suministrados por los developers que proporcionan a los developers una selección de paquetes reutilizables que son una parte importante del ecosistema de RT-Thread. El ecosistema de paquetes es fundamental para la elección de un sistema operativo porque estos paquetes son altamente reutilizables y modulares, lo que facilita a los developers de aplicaciones la construcción del sistema que desean en el menor tiempo posible. RT-Thread es compatible con más de 370 paquetes de software.
|
||||||
|
|
||||||
|
## Características de RT-Thread
|
||||||
|
|
||||||
|
- Diseñado para dispositivos con recursos limitados, el núcleo mínimo requiere sólo 1,2 KB de RAM y 3 KB de Flash.
|
||||||
|
- Una variedad de interfaces estándar, como POSIX, CMSIS, entorno de aplicación C++.
|
||||||
|
- Tiene ricos componentes y un ecosistema de paquetes próspero y de rápido crecimiento.
|
||||||
|
- Estilo de código elegante, fácil de usar, leer y dominar.
|
||||||
|
- Alta escalabilidad. RT-Thread tiene una arquitectura de software escalable de alta calidad, acoplamiento suelto, modularidad, es fácil de adaptar y ampliar.
|
||||||
|
- Admite aplicaciones de alto rendimiento.
|
||||||
|
- Es compatible con todas las herramientas de compilación principales, como GCC, Keil e IAR.
|
||||||
|
- Admite una amplia gama de <a href="https://www.rt-thread.io/board.html">arquitecturas y chips</a>.
|
||||||
|
|
||||||
|
## Code Catalogue
|
||||||
|
|
||||||
|
El catálogo de código fuente de RT-Thread se muestra como sigue:
|
||||||
|
|
||||||
|
| Name | Descripción |
|
||||||
|
| ------------- | ------------------------------------------------------- |
|
||||||
|
| BSP | Board Support Package basado en la portación de varias placas de desarrollo |
|
||||||
|
| componentes | Componentes, como finsh shell, sistema de archivos, pila de protocolos, etc.|
|
||||||
|
| documentación | Documentos relacionados, como el estilo de codificación, doxygen, etc. |
|
||||||
|
| ejemplos | Código de ejemplo relacionado |
|
||||||
|
| incluir | Archivos de cabecera del kernel RT-Thread. |
|
||||||
|
| libcpu | Código de portabilidad de CPUs como ARM/MIPS/RISC-V, etc.|
|
||||||
|
| src | Los archivos fuente del kernel RT-Thread. |
|
||||||
|
| herramientas | Los archivos de script para la herramienta de construcción de comandos de RT-Thread. |
|
||||||
|
|
||||||
|
RT-Thread ha sido portado para casi 200 placas de desarrollo, la mayoría de los BSPs soportan el MDK, el entorno de desarrollo IAR y el compilador GCC, y han proporcionado un proyecto MDK e IAR por defecto, que permite a los usuarios añadir su propio código de aplicación directamente basado en el proyecto. Cada BSP tiene una estructura de directorio similar, y la mayoría de los BSPs proporcionan un archivo README.md, que es un archivo con formato markdown que contiene la introducción básica del BSP, y presenta cómo empezar a usar el BSP de forma sencilla.
|
||||||
|
|
||||||
|
# Recursos
|
||||||
|
|
||||||
|
## Arquitecturas Compatibles
|
||||||
|
|
||||||
|
RT-Thread es compatible con muchas arquitecturas, y ha cubierto las principales arquitecturas de las aplicaciones actuales. Arquitectura y fabricante de chips implicados:
|
||||||
|
|
||||||
|
- **ARM Cortex-M0/M0+**:manufacturers like ST
|
||||||
|
- **ARM Cortex-M3**:manufacturers like ST、Winner Micro、MindMotion, ect.
|
||||||
|
- **ARM Cortex-M4**:manufacturers like ST、Infineon、Nuvoton、NXP、[Nordic](https://github.com/RT-Thread/rt-thread/tree/master/bsp/nrf5x)、GigaDevice、Realtek、Ambiq Micro, ect.
|
||||||
|
- **ARM Cortex-M7**:manufacturers like ST、NXP
|
||||||
|
- **ARM Cortex-M23**:manufacturers like GigaDevice
|
||||||
|
- **ARM Cortex-M33**:manufacturers like ST
|
||||||
|
- **ARM Cortex-R4**
|
||||||
|
- **ARM Cortex-A8/A9**:manufacturers like NXP
|
||||||
|
- **ARM7**:manufacturers like Samsung
|
||||||
|
- **ARM9**:manufacturers like Allwinner、Xilinx 、GOKE
|
||||||
|
- **ARM11**:manufacturers like Fullhan
|
||||||
|
- **MIPS32**:manufacturers like loongson、Ingenic
|
||||||
|
- **RISC-V RV32E/RV32I[F]/RV64[D]**:manufacturers like Hifive、[Kendryte](https://github.com/RT-Thread/rt-thread/tree/master/bsp/k210)、[bouffalo_lab](https://github.com/RT-Thread/rt-thread/tree/master/bsp/bouffalo_lab)、[Nuclei](https://nucleisys.com/)、[T-Head](https://www.t-head.cn/)、[HPMicro](https://github.com/RT-Thread/rt-thread/tree/master/bsp/hpmicro)
|
||||||
|
- **ARC**:manufacturers like SYNOPSYS
|
||||||
|
- **DSP**:manufacturers like TI
|
||||||
|
- **C-Sky**
|
||||||
|
- **x86**
|
||||||
|
|
||||||
|
## IDE y compilador compatibles
|
||||||
|
|
||||||
|
Los principales IDE/compiladores soportados por RT-Thread son:
|
||||||
|
|
||||||
|
- RT-Thread Studio IDE
|
||||||
|
- MDK KEIL
|
||||||
|
- IAR
|
||||||
|
- GCC
|
||||||
|
|
||||||
|
## RT-Thread Studio IDE
|
||||||
|
|
||||||
|
[User Manual](https://www.rt-thread.io/document/site/rtthread-studio/um/studio-user-manual/) | [Tutorial Videos](https://youtu.be/ucq5eJgZIQg)
|
||||||
|
|
||||||
|
RT-Thread Studio IDE (también conocido como RT-Studio) es un entorno de desarrollo integrado construido por el equipo de RT-Thread. Cuenta con un sistema de configuración gráfica fácil de usar y una gran cantidad de paquetes de software y recursos de componentes. RT-Studio tiene las características de creación, configuración y gestión de proyectos, así como la edición de código, la gestión del SDK, la configuración de la construcción, la configuración de la depuración, la descarga del programa y la depuración. Buscamos que el uso de RT-Studio sea lo más intuitivo posible, reduciendo la duplicación de trabajo y mejorando la eficiencia del desarrollo.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Herramienta Env
|
||||||
|
|
||||||
|
[User Manual](documentation/env/env.md) | [Tutorial Videos](https://www.youtube.com/watch?v=dEK94o_YoSo)
|
||||||
|
|
||||||
|
En la etapa inicial, el equipo de RT-Thread también creó una herramienta auxiliar llamada Env. Es una herramienta auxiliar con una TUI (interfaz de usuario basada en texto). Los desarrolladores pueden utilizar la herramienta Env para configurar y generar los proyectos GCC, Keil MDK e IAR.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
# Cómo Empezar
|
||||||
|
|
||||||
|
[Guía de programación RT-Thread](https://www.rt-thread.io/document/site/tutorial/quick-start/introduction/introduction/) | [RT-Thread Studio IDE](https://www.rt-thread.io/studio.html) | [Kernel Sample](https://github.com/RT-Thread-packages/kernel-sample) | [RT-Thread Guía de iniciación](https://www.youtube.com/watch?v=ZMi1O-Rr7yc&list=PLXUV89C_M3G5KVw2IerI-pqApdSM_IaZo)
|
||||||
|
|
||||||
|
Basado en [STM32F103 BluePill](https://github.com/RT-Thread/rt-thread/tree/master/bsp/stm32/stm32f103-blue-pill) | [Raspberry Pi Pico](https://github.com/RT-Thread/rt-thread/tree/master/bsp/raspberry-pico)
|
||||||
|
|
||||||
|
## Simulator
|
||||||
|
|
||||||
|
El BSP de RT-Thread puede compilarse directamente y descargarse en la placa de desarrollo correspondiente para su uso. Además, RT-Thread también proporciona el BSP qemu-vexpress-a9, que puede utilizarse sin plataforma de hardware. Consulte la guía de inicio más abajo para más detalles. [Windows](documentation/quick-start/quick_start_qemu/quick_start_qemu.md) | [Linux Ubuntu](documentation/quick-start/quick_start_qemu/quick_start_qemu_linux.md) | [Mac OS](documentation/quick-start/quick_start_qemu/quick_start_qemu_macos.md)
|
||||||
|
|
||||||
|
# Licencia
|
||||||
|
|
||||||
|
RT-Thread es un software de código abierto y ha sido licenciado bajo la Licencia Apache Versión 2.0 desde la v3.1.1. La información sobre la licencia y los derechos de autor puede verse generalmente al principio del código:
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
* ...
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
# Comunidad
|
||||||
|
|
||||||
|
RT-Thread está muy agradecido por el apoyo de todos los desarrolladores de la comunidad, y si tienes alguna idea, sugerencia o pregunta en el proceso de uso de RT-Thread, se puede llegar a RT-Thread por los siguientes medios, y también estamos actualizando RT-Thread en tiempo real en estos canales. Al mismo tiempo, cualquier pregunta se puede hacer en [la sección de problemas del repositorio de RT-Thread](https://github.com/RT-Thread/rt-thread/issues) or [en el foro de RT-Thread](https://club.rt-thread.io/), y los miembros de la comunidad la responderán.
|
||||||
|
|
||||||
|
[Website](https://www.rt-thread.io) | [Github](https://github.com/RT-Thread/rt-thread) | [Twitter](https://twitter.com/rt_thread) | [LinkedIn](https://www.linkedin.com/company/rt-thread-iot-os/posts/?feedView=all) | [Youtube](https://www.youtube.com/channel/UCdDHtIfSYPq4002r27ffqPw) | [Facebook](https://www.facebook.com/RT-Thread-IoT-OS-110395723808463/?modal=admin_todo_tour) | [Medium](https://rt-thread.medium.com/)
|
||||||
|
|
||||||
|
# Contribución
|
||||||
|
|
||||||
|
Si estás interesado en RT-Thread y quieres unirte al desarrollo de RT-Thread y convertirte en un contribuidor de código, por favor consulta la [Guía de Contribución de Código.](documentation/contribution_guide/contribution_guide.md).
|
183
README_zh.md
Normal file
183
README_zh.md
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
<p align="center">
|
||||||
|
<img src="documentation/figures/logo.png" width="60%" >
|
||||||
|
</p>
|
||||||
|
|
||||||
|
[English](README.md) | **中文** | [Español](README_es.md) | [Deutsch](README_de.md)
|
||||||
|
|
||||||
|
[](https://github.com/RT-Thread/rt-thread/stargazers)
|
||||||
|
[](https://gitee.com/rtthread/rt-thread/stargazers)
|
||||||
|
[](https://github.com/RT-Thread/rt-thread/blob/master/LICENSE)
|
||||||
|
[](https://github.com/RT-Thread/rt-thread/releases)
|
||||||
|
[](https://gitter.im/RT-Thread/rt-thread?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
|
[](https://github.com/RT-Thread/rt-thread/pulls)
|
||||||
|
[](https://github.com/RT-Thread/rt-thread/pulls)
|
||||||
|
|
||||||
|
## 简介
|
||||||
|
|
||||||
|
RT-Thread诞生于2006年,是一款以开源、中立、社区化发展起来的物联网操作系统。
|
||||||
|
RT-Thread主要采用 C 语言编写,浅显易懂,且具有方便移植的特性(可快速移植到多种主流 MCU 及模组芯片上)。RT-Thread把面向对象的设计方法应用到实时系统设计中,使得代码风格优雅、架构清晰、系统模块化并且可裁剪性非常好。
|
||||||
|
|
||||||
|
RT-Thread有完整版和Nano版,对于资源受限的微控制器(MCU)系统,可通过简单易用的工具,裁剪出仅需要 3KB Flash、1.2KB RAM 内存资源的 NANO 内核版本;而相对资源丰富的物联网设备,可使用RT-Thread完整版,通过在线的软件包管理工具,配合系统配置工具实现直观快速的模块化裁剪,并且可以无缝地导入丰富的软件功能包,实现类似 Android 的图形界面及触摸滑动效果、智能语音交互效果等复杂功能。
|
||||||
|
|
||||||
|
## **RT-Thread架构**
|
||||||
|
|
||||||
|
RT-Thread是一个集实时操作系统(RTOS)内核、中间件组件的物联网操作系统,架构如下:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- 内核层:RT-Thread内核,是 RT-Thread的核心部分,包括了内核系统中对象的实现,例如多线程及其调度、信号量、邮箱、消息队列、内存管理、定时器等;libcpu/BSP(芯片移植相关文件 / 板级支持包)与硬件密切相关,由外设驱动和 CPU 移植构成。
|
||||||
|
|
||||||
|
- 组件与服务层:组件是基于 RT-Thread内核之上的上层软件,例如虚拟文件系统、FinSH命令行界面、网络框架、设备框架等。采用模块化设计,做到组件内部高内聚,组件之间低耦合。
|
||||||
|
|
||||||
|
|
||||||
|
- RT-Thread软件包:运行于 RT-Thread物联网操作系统平台上,面向不同应用领域的通用软件组件,由描述信息、源代码或库文件组成。RT-Thread提供了开放的软件包平台,这里存放了官方提供或开发者提供的软件包,该平台为开发者提供了众多可重用软件包的选择,这也是 RT-Thread生态的重要组成部分。软件包生态对于一个操作系统的选择至关重要,因为这些软件包具有很强的可重用性,模块化程度很高,极大的方便应用开发者在最短时间内,打造出自己想要的系统。RT-Thread已经支持的软件包数量已经达到450+。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## RT-Thread的特点
|
||||||
|
|
||||||
|
- 资源占用极低,超低功耗设计,最小内核(Nano版本)仅需1.2KB RAM,3KB Flash。
|
||||||
|
|
||||||
|
- 组件丰富,繁荣发展的软件包生态 。
|
||||||
|
|
||||||
|
- 简单易用 ,优雅的代码风格,易于阅读、掌握。
|
||||||
|
|
||||||
|
- 高度可伸缩,优质的可伸缩的软件架构,松耦合,模块化,易于裁剪和扩展。
|
||||||
|
|
||||||
|
- 强大,支持高性能应用。
|
||||||
|
|
||||||
|
- 跨平台、芯片支持广泛。
|
||||||
|
|
||||||
|
|
||||||
|
## **代码目录**
|
||||||
|
|
||||||
|
RT-Thread源代码目录结构如下图所示:
|
||||||
|
|
||||||
|
| 名称 | 描述 |
|
||||||
|
| ------------- | ------------------------------------------------------- |
|
||||||
|
| BSP | Board Support Package(板级支持包)基于各种开发板的移植 |
|
||||||
|
| components | RT-Thread 的各个组件代码,例如 finsh,gui 等。 |
|
||||||
|
| documentation | 相关文档,如编码规范等 |
|
||||||
|
| examples | 相关示例代码 |
|
||||||
|
| include | RT-Thread 内核的头文件。 |
|
||||||
|
| libcpu | 各类芯片的移植代码。 |
|
||||||
|
| src | RT-Thread 内核的源文件。 |
|
||||||
|
| tools | RT-Thread 命令构建工具的脚本文件。 |
|
||||||
|
|
||||||
|
目前RT-Thread已经针对将近90种开发板做好了移植,大部分 BSP 都支持 MDK﹑IAR开发环境和GCC编译器,并且已经提供了默认的 MDK 和 IAR 工程,用户可以直接基于这个工程添加自己的应用代码。 每个 BSP 的目录结构高度统一,且都提供一个 README.md 文件,包含了对这个 BSP 的基本介绍,以及相应的说明,方便用户快速上手。
|
||||||
|
|
||||||
|
Env 是RT-Thread推出的开发辅助工具,针对基于RT-Thread操作系统的项目工程,提供编译构建环境、图形化系统配置及软件包管理功能。其内置的 menuconfig 提供了简单易用的配置剪裁工具,可对内核、组件和软件包进行自由裁剪,使系统以搭积木的方式进行构建。
|
||||||
|
|
||||||
|
[下载 Env 工具](https://www.rt-thread.org/download.html#download-rt-thread-env-tool)
|
||||||
|
|
||||||
|
[Env 用户手册](https://www.rt-thread.org/document/site/#/development-tools/env/env)
|
||||||
|
|
||||||
|
|
||||||
|
# 资源文档
|
||||||
|
|
||||||
|
## **硬件支持**
|
||||||
|
|
||||||
|
RT-Thread RTOS 支持许多架构,并且已经涵盖了当前应用中的主要架构。涉及的架构和芯片制造商有:
|
||||||
|
|
||||||
|
- ARM Cortex-M0/M0+:如芯片制造商 ST
|
||||||
|
- ARM Cortex-M3:如芯片制造商 ST、全志、灵动等.
|
||||||
|
- ARM Cortex-M4:如芯片制造商 ST、Infineon、Nuvoton、NXP、[Nordic](https://github.com/RT-Thread/rt-thread/tree/master/bsp/nrf5x)、GigaDevice、Realtek、Ambiq Micro等
|
||||||
|
- ARM Cortex-M7:如芯片制造商 ST、NXP
|
||||||
|
- ARM Cortex-M23:如芯片制造商 GigaDevice
|
||||||
|
- ARM Cortex-M33:如芯片制造商 ST
|
||||||
|
- ARM Cortex-R4
|
||||||
|
- ARM Cortex-A8/A9:如芯片制造商 NXP
|
||||||
|
- ARM7:如芯片制造商Samsung
|
||||||
|
- ARM9:如芯片制造商Allwinner、Xilinx 、GOKE
|
||||||
|
- ARM11:如芯片制造商Fullhan
|
||||||
|
- MIPS32:如芯片制造商loongson、Ingenic
|
||||||
|
- RISC-V RV32E/RV32I[F]/RV64[D]:如芯片制造商sifive、[嘉楠Kendryte](https://github.com/RT-Thread/rt-thread/tree/master/bsp/k210)、[博流](https://github.com/RT-Thread/rt-thread/tree/master/bsp/bouffalo_lab)、[芯来Nuclei](https://nucleisys.com/)、[平头哥T-Head](https://www.t-head.cn/)、[先楫](https://github.com/RT-Thread/rt-thread/tree/master/bsp/hpmicro)
|
||||||
|
- ARC:如芯片制造商SYNOPSYS
|
||||||
|
- DSP:如芯片制造商 TI
|
||||||
|
- C-Sky
|
||||||
|
- x86
|
||||||
|
|
||||||
|
|
||||||
|
## **支持的 IDE 和编译器**
|
||||||
|
|
||||||
|
RT-Thread主要支持的IDE/编译器包括:
|
||||||
|
|
||||||
|
- MDK KEIL
|
||||||
|
|
||||||
|
- IAR
|
||||||
|
|
||||||
|
- Gcc
|
||||||
|
|
||||||
|
- RT-Thread Studio
|
||||||
|
|
||||||
|
使用基于 Python 的 [scons](http://www.scons.org/) 进行命令行生成。
|
||||||
|
|
||||||
|
RT-Thread Studio演示:
|
||||||
|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
## **快速上手**
|
||||||
|
|
||||||
|
RT-Thread BSP可以直接编译并下载到相应的开发板使用。此外,RT-Thread还提供 qemu-vexpress-a9 BSP,无需硬件平台即可使用。有关详细信息,请参阅下面的入门指南。
|
||||||
|
|
||||||
|
[QEMU 入门指南(Windows)](documentation/quick-start/quick_start_qemu/quick_start_qemu.md)
|
||||||
|
|
||||||
|
[QEMU 入门指南(Ubuntu)](documentation/quick-start/quick_start_qemu/quick_start_qemu_linux.md)
|
||||||
|
|
||||||
|
|
||||||
|
## 文档
|
||||||
|
|
||||||
|
[文档中心](https://www.rt-thread.org/document/site/ ) | [编程指南](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/basic/basic )
|
||||||
|
|
||||||
|
[应用 RT-Thread 实现蜂鸣器播放器教程](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/tutorial/beep-player/README?id=%e5%ba%94%e7%94%a8-rt-thread-%e5%ae%9e%e7%8e%b0%e8%9c%82%e9%b8%a3%e5%99%a8%e6%92%ad%e6%94%be%e5%99%a8) | [分布式温度监控系统教程](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/tutorial/temperature-system/README?id=%e5%88%86%e5%b8%83%e5%bc%8f%e6%b8%a9%e5%ba%a6%e7%9b%91%e6%8e%a7%e7%b3%bb%e7%bb%9f ) | [智能车连载教程](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/tutorial/smart-car/README?id=%e6%99%ba%e8%83%bd%e8%bd%a6%e8%bf%9e%e8%bd%bd%e6%95%99%e7%a8%8b%e7%ae%80%e4%bb%8b )
|
||||||
|
|
||||||
|
## 例程
|
||||||
|
|
||||||
|
[内核示例](https://github.com/RT-Thread-packages/kernel-sample) | [设备示例代码](https://github.com/RT-Thread-packages/peripheral-sample ) | [文件系统示例代码](https://github.com/RT-Thread-packages/filesystem-sample ) | [网络示例代码](https://github.com/RT-Thread-packages/network-sample ) | [RT-Thread API参考手册](https://www.rt-thread.org/document/api/ )
|
||||||
|
|
||||||
|
[基于STM32L475 IoT Board 开发板SDK](https://github.com/RT-Thread/IoT_Board) | [基于W601 IoT Board 开发板SDK](https://github.com/RT-Thread/W601_IoT_Board)
|
||||||
|
|
||||||
|
## 视频
|
||||||
|
|
||||||
|
RT-Thread视频中心提供了一系列RT-Thread相关教程及分享内容。
|
||||||
|
|
||||||
|
如:内核入门系列 | Env系列 | 网络系列 | Nano移植系列 | RT-Thread Studio系列 | 柿饼UI系列 | 答疑直播系列 | 社区作品系列
|
||||||
|
|
||||||
|
更多详情,请前往 [视频中心](https://www.rt-thread.org/page/video.html)
|
||||||
|
|
||||||
|
# **许可协议**
|
||||||
|
|
||||||
|
RT-Thread 系统完全开源,遵循 Apache License 2.0 开源许可协议,可以免费在商业产品中使用,并且不需要公开私有代码,没有潜在商业风险。
|
||||||
|
|
||||||
|
```
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
# 社区支持
|
||||||
|
|
||||||
|
RT-Thread非常感谢所有社区小伙伴的支持,在使用RT-Thread的过程中若您有任何的想法,建议或疑问都可通过以下方式联系到 RT-Thread,我们也实时在这些频道更新RT-Thread的最新讯息。同时,任何问题都可以在 [论坛](https://club.rt-thread.org/index.html) 中提出,社区成员将回答这些问题。
|
||||||
|
|
||||||
|
[官网]( https://www.rt-thread.org) | [论坛]( https://www.rt-thread.org/qa/forum.php) | [哔哩哔哩官方账号](https://space.bilibili.com/423462075?spm_id_from=333.788.b_765f7570696e666f.2) | [微博官方账号](https://weibo.com/rtthread?is_hot=1) | [知乎官方账号](https://www.zhihu.com/topic/19964581/hot)
|
||||||
|
|
||||||
|
RT-Thread微信公众号:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
# 贡献代码
|
||||||
|
|
||||||
|
如果您对RT-Thread感兴趣,并希望参与RT-Thread的开发并成为代码贡献者,请参阅[代码贡献指南](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/development-guide/github/github)。
|
||||||
|
|
||||||
|
## 感谢以下小伙伴对本仓库的贡献!
|
||||||
|
|
||||||
|
<a href="https://github.com/RT-Thread/rt-thread/graphs/contributors">
|
||||||
|
<img src="https://contrib.rocks/image?repo=RT-Thread/rt-thread" />
|
||||||
|
</a>
|
833
bsp/Copyright_Notice.md
Normal file
833
bsp/Copyright_Notice.md
Normal file
|
@ -0,0 +1,833 @@
|
||||||
|
# 版权声明 Copyright Notice
|
||||||
|
|
||||||
|
RT-Thread 是一套开源、开放的操作系统平台,自 3.1.1 版本开始以 Apache License v2.0 许可协议发布。
|
||||||
|
|
||||||
|
芯片厂商外设函数库或者厂商固件,按厂商的许可进行授权,并以原有许可协议发布。
|
||||||
|
|
||||||
|
RT-Thread is an open source operating system, which is released under Apache License V2.0 since version 3.1.1.
|
||||||
|
|
||||||
|
The peripheral library or firmware library of the chip manufacturer is authorized according to the manufacturer's license, and these files are released according to the original license agreement.
|
||||||
|
|
||||||
|
## BSP's License and Copyright:
|
||||||
|
|
||||||
|
### acm32f0x0-nucleo
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2021, AisinoChip
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/acm32f0x0-nucleo/libraries
|
||||||
|
|
||||||
|
### apm32
|
||||||
|
|
||||||
|
bsp 列表:
|
||||||
|
- apm32f103xe-minibroard
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: GEEHY SOFTWARE PACKAGE LICENSE
|
||||||
|
|
||||||
|
Copyright: Copyright (C) 2020-2022 Geehy Semiconductor
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp\apm32\libraries\APM32F10x_Library\APM32F10x_StdPeriphDriver
|
||||||
|
- bsp\apm32\libraries\APM32F10x_Library\Device
|
||||||
|
- bsp\apm32\libraries\APM32F10x_Library\USB_Device_Lib
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright (c) 2009-2018 Arm Limited
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp\apm32\libraries\APM32F10x_Library\CMSIS\Include
|
||||||
|
|
||||||
|
### apollo2
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2017, Ambiq Micro
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/apollo2/libraries
|
||||||
|
|
||||||
|
### at32
|
||||||
|
|
||||||
|
License: st-mcd-2.0
|
||||||
|
|
||||||
|
Copyright: (c) COPYRIGHT 2018 ArteryTek
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/at32/at32f407-start/board/msp
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2010-2015 ARM Limited
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/at32/Libraries/AT32_Std_Driver/CMSIS
|
||||||
|
|
||||||
|
### avr32uc3b0
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2009 Atmel Corporation
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/avr32uc3b0/SOFTWARE_FRAMEWORK
|
||||||
|
|
||||||
|
### CME_M7
|
||||||
|
|
||||||
|
License: st-mcd-2.0
|
||||||
|
|
||||||
|
Copyright: (c) COPYRIGHT 2013 Capital-micro
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/CME_M7/CMSIS/CME_M7
|
||||||
|
- bsp/CME_M7/StdPeriph_Driver
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2009 - 2013 ARM LIMITED
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/CME_M7/CMSIS/CMSIS
|
||||||
|
|
||||||
|
### efm32
|
||||||
|
|
||||||
|
License: zlib
|
||||||
|
|
||||||
|
Copyright: (C) Copyright 2012 Energy Micro AS, http://www.energymicro.com
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/efm32/EFM32_Gxxx_DK
|
||||||
|
- bsp/efm32/EFM32GG_DK3750
|
||||||
|
- bsp/efm32/graphics
|
||||||
|
- bsp/efm32/Libraries/Device/EnergyMicro
|
||||||
|
- bsp/efm32/Libraries/emlib
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: arm-cortex-mx
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2009-2012 ARM Limited
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/efm32/Libraries/CMSIS/Include
|
||||||
|
|
||||||
|
### essemi
|
||||||
|
|
||||||
|
License: 未注明
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2018 Shanghai Eastsoft Microelectronics Co., Ltd.
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/essemi/es32f0271/libraries/CMSIS/Device
|
||||||
|
- bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver
|
||||||
|
- bsp/essemi/es32f0271/libraries/usblib
|
||||||
|
- bsp/essemi/es32f0334/libraries/ES32F033x_ALD_StdPeriph_Driver
|
||||||
|
- bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver
|
||||||
|
- bsp/essemi/es32f369x/libraries/ES32F36xx_ALD_StdPeriph_Driver
|
||||||
|
- bsp/essemi/es8p508x/libraries/CMSIS
|
||||||
|
- bsp/essemi/es8p508x/libraries/Library
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2013 ARM LIMITED
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/essemi/es32f0271/libraries/CMSIS/RTOS
|
||||||
|
- bsp/essemi/es32f0334/libraries/CMSIS/Include
|
||||||
|
- bsp/essemi/es32f0654/libraries/CMSIS/Include
|
||||||
|
- bsp/essemi/es8p508x/libraries/CMSIS
|
||||||
|
|
||||||
|
###fm33lc026
|
||||||
|
|
||||||
|
License: Mulan PSL v1
|
||||||
|
|
||||||
|
Copyright: Copyright (c) [2019] [Fudan Microelectronics]
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/fm33lc026\libraries\FM33LC0xx_FL_Driver
|
||||||
|
- bsp/fm33lc026\libraries\FM
|
||||||
|
|
||||||
|
### frdm-k64f
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/frdm-k64f/board
|
||||||
|
- bsp/frdm-k64f/device
|
||||||
|
|
||||||
|
### gd32
|
||||||
|
|
||||||
|
bsp 列表:
|
||||||
|
- gd32103c-eval
|
||||||
|
- gd32303e-eval
|
||||||
|
- gd32450z-eval
|
||||||
|
- gd32e230k-start
|
||||||
|
- gd32vf103v-eval
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: 未注明
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2017 GigaDevice
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral
|
||||||
|
- bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2018, GigaDevice Semiconductor Inc.
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/gd32e230k-start/Libraries/CMSIS/GD
|
||||||
|
- bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral
|
||||||
|
- bsp/gd32vf103v-eval/board/gd32vf103_libopt.h
|
||||||
|
- bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2012 ARM LIMITED
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/gd32103c-eval/Libraries/CMSIS/core_cm3.h
|
||||||
|
- bsp/gd32303e-eval/Libraries/CMSIS/core
|
||||||
|
- bsp/gd32303e-eval/Libraries/CMSIS/GD/GD32F30x/Include
|
||||||
|
- bsp/gd32450z-eval/Libraries/CMSIS/core
|
||||||
|
- bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Include/system
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: arm-cortex-mx
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2009-2012 ARM Limited
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/gd32103c-eval/Libraries/CMSIS/core
|
||||||
|
- bsp/gd32303e-eval/Libraries/CMSIS/core
|
||||||
|
|
||||||
|
### hc32f4a0
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2020, Huada Semiconductor Co., Ltd.
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/hc32f4a0/Libraries/CMSIS
|
||||||
|
- bsp/hc32f4a0/Libraries/HC32F4A0_StdPeriph_Driver
|
||||||
|
|
||||||
|
### hc32f460
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2020, Huada Semiconductor Co., Ltd.
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/hc32f460/Libraries/CMSIS
|
||||||
|
- bsp/hc32f460/Libraries/HC32F460_StdPeriph_Driver
|
||||||
|
|
||||||
|
### hc32l196
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2020, Huada Semiconductor Co., Ltd.
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/hc32l196/Libraries/CMSIS
|
||||||
|
- bsp/hc32l196/Libraries/HC32L196_StdPeriph_Driver
|
||||||
|
|
||||||
|
### hk32
|
||||||
|
|
||||||
|
License: free-unknown
|
||||||
|
|
||||||
|
Copyright: Copyright (c) HKMicroChip
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/hk32/libraries/HK32F0xx_StdPeriph_Driver
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2009 - 2013 ARM LIMITED
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/hk32/libraries/HK32F0xx_StdPeriph_Driver/CMSIS
|
||||||
|
|
||||||
|
### imx6sx
|
||||||
|
|
||||||
|
License: other-permissive
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2012, Freescale Semiconductor, Inc.
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/imx6sx/cortex-a9/board
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: bsd-new、robert-hubley、other-permissive、proprietary-license
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2012, Freescale Semiconductor, Inc.
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/imx6sx/iMX6_Platform_SDK
|
||||||
|
|
||||||
|
### imx6ul
|
||||||
|
|
||||||
|
License: bsd-new、proprietary-license、robert-hubley
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2012, Freescale Semiconductor, Inc.
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/imx6ul/platform
|
||||||
|
|
||||||
|
### imxrt
|
||||||
|
|
||||||
|
License: clear-bsd
|
||||||
|
|
||||||
|
Copyright: Copyright 2016 - 2017 NXP
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/imxrt/imxrt1052-nxp-evk/xip
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright 2016 - 2017 NXP
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/imxrt/imxrt1064-nxp-evk/board/MCUX_Config/clock_config.c
|
||||||
|
- bsp/imxrt/imxrt1064-nxp-evk/xip
|
||||||
|
- bsp/imxrt/libraries/drivers/drv_sdram.c
|
||||||
|
- bsp/imxrt/libraries/drivers/usb
|
||||||
|
- bsp/imxrt/libraries/MIMXRT1050/MIMXRT1052
|
||||||
|
- bsp/imxrt/libraries/MIMXRT1064/MIMXRT1064
|
||||||
|
|
||||||
|
### lm
|
||||||
|
|
||||||
|
bsp 列表:
|
||||||
|
|
||||||
|
- lm3s9b9x
|
||||||
|
- lm3s8962
|
||||||
|
- lm4f232
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: unknown-license-reference 或 proprietary-license
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2005-2011 Texas Instruments Incorporated
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/lm3s8962/Libraries
|
||||||
|
- bsp/lm3s9b9x/Libraries
|
||||||
|
- bsp/lm4f232/Libraries
|
||||||
|
|
||||||
|
### lpcxxx
|
||||||
|
|
||||||
|
bsp 列表:
|
||||||
|
|
||||||
|
- lpc408x
|
||||||
|
- lpc54114-lite
|
||||||
|
- lpc54608-LPCXpresso
|
||||||
|
- lpc55sxx
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: arm-cortex-mx
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2009 ARM Limited
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/lpc176x/CMSIS/CM3
|
||||||
|
- bsp/lpc178x/CMSIS/CM3
|
||||||
|
- bsp/lpc408x/Libraries/CMSIS
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: nxp-warranty-disclaimer
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2011, NXP Semiconductor
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/lpc178x/CMSIS/CM3
|
||||||
|
- bsp/lpc178x/drivers
|
||||||
|
- bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x
|
||||||
|
- bsp/lpc43xx/Libraries/Device/NXP/LPC43xx
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2009 - 2013 ARM Limited
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/lpc176x/CMSIS/CMSI
|
||||||
|
- bsp/lpc43xx/Libraries/CMSIS
|
||||||
|
- bsp/lpc5410x/Libraries/CMSIS
|
||||||
|
- bsp/lpc54608-LPCXpresso/SDK_2.2_LPCXpresso54608 (Copyright 2016-2017 NXP)
|
||||||
|
- bsp/lpc55sxx/Libraries/LPC55S6X (Copyright 2016-2018 NXP)
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: nxp-microcontroller-proprietary
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2011, NXP Semiconductor
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/lpc408x/Libraries/Drivers
|
||||||
|
- bsp/lpc5410x/Libraries
|
||||||
|
- bsp/lpc824/Libraries
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: clear-bsd
|
||||||
|
|
||||||
|
Copyright: Copyright 2016-2018 NXP
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/lpc54114-lite/Libraries/devices/LPC54114
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: zlib
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2013-2014 ARM Ltd.
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/lpc54608-LPCXpresso/SDK_2.2_LPCXpresso54608
|
||||||
|
|
||||||
|
### maxim
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2016 Maxim Integrated Products, Inc.
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/maxim/libraries/MAX32660PeriphDriver/CMSIS/Core
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: x11-xconsortium
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2016 Maxim Integrated Products, Inc.
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/maxim/libraries/MAX32660PeriphDriver
|
||||||
|
|
||||||
|
### mb9bf
|
||||||
|
|
||||||
|
bsp 列表:
|
||||||
|
|
||||||
|
- mb9bf500r
|
||||||
|
- mb9bf506r
|
||||||
|
- mb9bf568r
|
||||||
|
- mb9bf618s
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: arm-cortex-mx
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2009-2010 ARM Limited
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/mb9bf500r/CMSIS/core_xx
|
||||||
|
- bsp/mb9bf506r/CMSIS/core_xx
|
||||||
|
- bsp/mb9bf506r/libraries/CMSIS
|
||||||
|
- bsp/mb9bf568r/CMSIS/Include/core_xx
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: free-unknown
|
||||||
|
|
||||||
|
Copyright: (c) Fujitsu Semiconductor Europe GmbH
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/mb9bf500r/CMSIS
|
||||||
|
- sp/mb9bf506r/libraries/Device
|
||||||
|
- bsp/mb9bf618s/CMSIS/DeviceSupport
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: warranty-disclaimer
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2013 Spansion LLC.
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/mb9bf568r/CMSIS/DeviceSupport
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2009 - 2013 ARM LIMITED
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/mb9bf618s/CMSIS/Include
|
||||||
|
|
||||||
|
### mm32
|
||||||
|
|
||||||
|
bsp 列表:
|
||||||
|
|
||||||
|
- mm32l07x
|
||||||
|
- mm32l3xx
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2009 - 2013 ARM LIMITED
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/mm32l07x/Libraries/CMSIS
|
||||||
|
- bsp/mm32l3xx/Libraries/CMSIS/IAR_CORE
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: st-mcd-2.0
|
||||||
|
|
||||||
|
Copyright: (c) COPYRIGHT 2017 MindMotion
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/mm32l07x/Libraries/MM32L0xx
|
||||||
|
- bsp/mm32l3xx/Libraries/MM32L3xx
|
||||||
|
|
||||||
|
### nrf
|
||||||
|
|
||||||
|
bsp 列表:
|
||||||
|
|
||||||
|
- nrf5x
|
||||||
|
- nrf51822
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2009 - 2013 ARM LIMITED
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/nrf5x/libraries/cmsis
|
||||||
|
- bsp/nrf51822/Libraries/CMSIS
|
||||||
|
- bsp/nrf51822/Libraries/nrf51822 (Copyright (c) 2013, Nordic Semiconductor ASA)
|
||||||
|
|
||||||
|
### nuvoton
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2014 - 2015 Bosch Sensortec GmbH
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/nuvoton/libraries/nu_packages/BMX055/libraries/BMG160_driver
|
||||||
|
- bsp/nuvoton/libraries/nu_packages/BMX055/libraries/BMM050_driver
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: warranty-disclaimer
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2015 - 2016 Bosch Sensortec GmbH
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/nuvoton/libraries/nu_packages/BMX055/libraries/BMA2x2_driver
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: x11-xconsortium
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2019 Maxim Integrated Products, Inc.
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/nuvoton/libraries/nu_packages/MAX31875/libraries
|
||||||
|
|
||||||
|
### raspberry-pi
|
||||||
|
|
||||||
|
License: mit
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2018 bzt
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/raspberry-pi/raspi3-64/applications/test
|
||||||
|
|
||||||
|
### raspberry-pico
|
||||||
|
|
||||||
|
License: bsd-new、mit
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||||
|
|
||||||
|
Path: bsp/raspberry-pico/libraries/pico-sdk
|
||||||
|
|
||||||
|
### rm48x50
|
||||||
|
|
||||||
|
License: 未注明
|
||||||
|
|
||||||
|
Copyright: (c) Texas Instruments 2009-2013
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/rm48x50/HALCoGen
|
||||||
|
|
||||||
|
### rv32m1_vega
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright 2016-2017 NXP
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/rv32m1_vega/ri5cy/board
|
||||||
|
- bsp/rv32m1_vega/rv32m1_sdk_riscv
|
||||||
|
|
||||||
|
### rx
|
||||||
|
|
||||||
|
License: 未注明
|
||||||
|
|
||||||
|
Copyright: Copyright, 2011. Renesas Electronics Corporation and Renesas Solutions Corporation
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/rx/RPDL
|
||||||
|
|
||||||
|
### sam7x
|
||||||
|
|
||||||
|
License: bsd-atmel
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2006, Atmel Corporation
|
||||||
|
|
||||||
|
Copyright: Copyright: Copyright (c) 2006, Atmel Corporation
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/sam7x/drivers
|
||||||
|
|
||||||
|
### samd21
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2014-2015 Atmel Corporation
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/samd21/asflib_config
|
||||||
|
- bsp/samd21/sam_d2x_asflib
|
||||||
|
|
||||||
|
### simulator
|
||||||
|
|
||||||
|
License: bsd-new、bsd-original-uc
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2006 Paolo Abeni (Italy)、Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 The Regents of the University of California
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/simulator/pcap
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: zlib
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 1997-2017 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/simulator/SDL2-2.0.7
|
||||||
|
|
||||||
|
### smartfusion2
|
||||||
|
|
||||||
|
License: arm-cortex-mx
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2009 ARM Limited
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/smartfusion2/CMSIS/core
|
||||||
|
|
||||||
|
### stm32
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright:
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/stm32/libraries/STM32xxxx_HAL
|
||||||
|
- bsp/stm32/libraries/templates
|
||||||
|
- bsp/stm32/stm32_bsp_name/board/CubeMX_Config
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: mit
|
||||||
|
|
||||||
|
Copyright: COPYRIGHT 2011 STMicroelectronics
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/stm32/libraries (exclude bsp/stm32/libraries/HAL_Drivers)
|
||||||
|
|
||||||
|
### SYNWIT
|
||||||
|
|
||||||
|
bsp 列表:
|
||||||
|
|
||||||
|
- swm320
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: st-mcd-2.0
|
||||||
|
|
||||||
|
Copyright: COPYRIGHT 2012 Synwit Technology
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/swm320/libraries/CMSIS/DeviceSupport
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2009 - 2014 ARM LIMITED
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/swm320/libraries/CMSIS
|
||||||
|
|
||||||
|
### tae32f5300
|
||||||
|
|
||||||
|
License: BSD 3-Clause
|
||||||
|
|
||||||
|
Copyright (c) 2020 Tai-Action.
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/tae32f5300/Libraries/TAE32F53xx_StdPeriph_Driver
|
||||||
|
|
||||||
|
### tm4c
|
||||||
|
|
||||||
|
License: unknown-license-reference(bsd-new)
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2012-2017 Texas Instruments Incorporated
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/tm4c123bsp/libraries
|
||||||
|
- bsp/tm4c129x/libraries
|
||||||
|
|
||||||
|
### tms320f28379d
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2013-2018 Texas Instruments Incorporated - http://www.ti.com
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/tms320f28379d/libraries
|
||||||
|
|
||||||
|
### xplorer4330
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2009 - 2013 ARM LIMITED
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/xplorer4330/Libraries/CMSIS/Include
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
License: nxp-warranty-disclaimer
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2011, NXP Semiconductor
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/xplorer4330/Libraries/Device/NXP/LPC43xx
|
||||||
|
|
||||||
|
### zynqmp-r5-axu4ev
|
||||||
|
|
||||||
|
License: mit
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2014 - 2020 Xilinx, Inc.
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/zynqmp-r5-axu4ev/drivers/Zynq_HAL_Driver
|
||||||
|
|
||||||
|
### n32
|
||||||
|
|
||||||
|
License: 未注明
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2019, Nations Technologies Inc.
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/n32g452xx/n32g452xx-mini-system/board/msp
|
||||||
|
|
||||||
|
License: bsd-new
|
||||||
|
|
||||||
|
Copyright: Copyright (c) 2010-2015 ARM Limited
|
||||||
|
|
||||||
|
Path:
|
||||||
|
|
||||||
|
- bsp/n32g452xx/Libraries/N32_Std_Driver/CMSIS
|
179
bsp/README.md
Normal file
179
bsp/README.md
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
RT-THREAD bsp company list
|
||||||
|
|
||||||
|
- Simulator
|
||||||
|
- [qemu-vexpress-a9](qemu-vexpress-a9)
|
||||||
|
- [x86](x86)
|
||||||
|
- [simulator](simulator)
|
||||||
|
- [qemu-virt64-riscv](qemu-virt64-riscv)
|
||||||
|
- [qemu-virt64-aarch64](qemu-virt64-aarch64)
|
||||||
|
- [mipssim](mipssim)
|
||||||
|
- [juicevm](juicevm)
|
||||||
|
- [core-v-mcu](core-v-mcu)
|
||||||
|
- STM32
|
||||||
|
- [stm32](stm32) series
|
||||||
|
- NXP
|
||||||
|
- [lpc55sxx](lpc55sxx) series
|
||||||
|
- [imxrt](imxrt) series
|
||||||
|
- [frdm-k64f](frdm-k64f)
|
||||||
|
- [imx6sx](imx6sx)
|
||||||
|
- [imx6ul](imx6ul)
|
||||||
|
- [lpc824](lpc824)
|
||||||
|
- [lpc54608-LPCXpresso](lpc54608-LPCXpresso)
|
||||||
|
- [lpc54114-lite](lpc54114-lite)
|
||||||
|
- [lpc5410x](lpc5410x)
|
||||||
|
- [lpc43xx](lpc43xx)
|
||||||
|
- [lpc408x](lpc408x)
|
||||||
|
- [lpc2478](lpc2478)
|
||||||
|
- [lpc2148](lpc2148)
|
||||||
|
- [lpc178x](lpc178x)
|
||||||
|
- [lpc176x](lpc176x)
|
||||||
|
- [lpc1114](lpc1114)
|
||||||
|
- [xplorer4330](xplorer4330)
|
||||||
|
- [rv32m1_vega](rv32m1_vega)
|
||||||
|
- Renesas
|
||||||
|
- [renesas](renesas) series
|
||||||
|
- [rx](rx) series
|
||||||
|
- [upd70f3454](upd70f3454)
|
||||||
|
- [m16c62p](m16c62p)
|
||||||
|
- Nordic
|
||||||
|
- [nrf5x](nrf5x) series
|
||||||
|
- raspberry
|
||||||
|
- [raspberry-pi](raspberry-pi) series
|
||||||
|
- [raspberry-pico](raspberry-pico)
|
||||||
|
- TI
|
||||||
|
- [ti](ti) series
|
||||||
|
- [tms320c6678](tms320c6678)
|
||||||
|
- [tm4c129x](tm4c129x)
|
||||||
|
- [tm4c123bsp](tm4c123bsp)
|
||||||
|
- [rm48x50](rm48x50)
|
||||||
|
- [lm4f232](lm4f232)
|
||||||
|
- [lm3s9b9x](lm3s9b9x)
|
||||||
|
- [lm3s8962](lm3s8962)
|
||||||
|
- [dm365](dm365)
|
||||||
|
- [beaglebone](beaglebone)
|
||||||
|
- Samsung
|
||||||
|
- [wh44b0](wh44b0)
|
||||||
|
- [mini4020](mini4020)
|
||||||
|
- [mini2440](mini2440)
|
||||||
|
- Synopsys
|
||||||
|
- [synopsys](synopsys) series
|
||||||
|
- Espressif
|
||||||
|
- [ESP32_C3](ESP32_C3)
|
||||||
|
- MAXIM
|
||||||
|
- [maxim](maxim) series
|
||||||
|
- Microchip
|
||||||
|
- [at91](at91) series
|
||||||
|
- [smartfusion2](smartfusion2)
|
||||||
|
- [samd21](samd21)
|
||||||
|
- [sam7x](sam7x)
|
||||||
|
- [pic32ethernet](pic32ethernet)
|
||||||
|
- [microchip](microchip)
|
||||||
|
- [avr32uc3b0](avr32uc3b0)
|
||||||
|
- Infineon
|
||||||
|
- [fujitsu](fujitsu) series
|
||||||
|
- [Infineon](Infineon) series
|
||||||
|
- SiFive
|
||||||
|
- [hifive1](hifive1)
|
||||||
|
- [sparkfun-redv](sparkfun-redv)
|
||||||
|
- ADI
|
||||||
|
- [bf533](bf533)
|
||||||
|
- Silicon Labs
|
||||||
|
- [efm32](efm32) series
|
||||||
|
- Ambiq Micro
|
||||||
|
- [apollo2](apollo2)
|
||||||
|
- Xilinx
|
||||||
|
- [zynqmp-r5-axu4ev](zynqmp-r5-axu4ev)
|
||||||
|
- [taihu](taihu)
|
||||||
|
- [microblaze](microblaze)
|
||||||
|
- Altera
|
||||||
|
- [nios_ii](nios_ii)
|
||||||
|
- Nuclei
|
||||||
|
- [nuclei](nuclei)
|
||||||
|
- 灵动微MM32
|
||||||
|
- [mm32](mm32) series
|
||||||
|
- [mm32l3xx](mm32l3xx)
|
||||||
|
- [mm32f327x](mm32f327x)
|
||||||
|
- [mm32f103x](mm32f103x)
|
||||||
|
- 兆易创新GD32
|
||||||
|
- [gd32](gd32) series
|
||||||
|
- [gd32350r-eval](gd32350r-eval)
|
||||||
|
- [gd32450z-eval](gd32450z-eval)
|
||||||
|
- [gd32e230k-start](gd32e230k-start)
|
||||||
|
- [gd32vf103v-eval](gd32vf103v-eval)
|
||||||
|
- [gd32303e-eval](gd32303e-eval)
|
||||||
|
- [gd32107c-eval](gd32107c-eval)
|
||||||
|
- [gd32105c-eval](gd32105c-eval)
|
||||||
|
- Realtek
|
||||||
|
- [amebaz](amebaz)
|
||||||
|
- 国民科技N32
|
||||||
|
- [n32](n32) series
|
||||||
|
- [n32g452xx](n32g452xx)
|
||||||
|
- [mm32107x](mm32107x)
|
||||||
|
- 小华HC32
|
||||||
|
- [hc32](hc32) series
|
||||||
|
- [hc321196](hc321196)
|
||||||
|
- [hc321136](hc321136)
|
||||||
|
- 全志Allwinner
|
||||||
|
- [allwinner](allwinner) series
|
||||||
|
- [allwinner_tina](allwinner_tina)
|
||||||
|
- 雅特力AT32
|
||||||
|
- [at32](at32) series
|
||||||
|
- rockchip
|
||||||
|
- [rockchip](rockchip) serise
|
||||||
|
- 先楫
|
||||||
|
- [hpmicro](hpmicro) series
|
||||||
|
- 东软EastSoft
|
||||||
|
- [essemi](essemi) series
|
||||||
|
- 嘉楠canaan
|
||||||
|
- [K210](k210)
|
||||||
|
- 沁恒WCH
|
||||||
|
- [wch](wch) series
|
||||||
|
- 联德盛winnermicro
|
||||||
|
- [w60x](w60x)
|
||||||
|
- 泰为
|
||||||
|
- [tae32f5300](tae32f5300)
|
||||||
|
- Nuvoton
|
||||||
|
- [nuvoton](nuvoton) series
|
||||||
|
- 飞腾
|
||||||
|
- [phytium](phytium) series
|
||||||
|
- [ft2004](ft2004)
|
||||||
|
- 合宙
|
||||||
|
- [airm2m](airm2m) series
|
||||||
|
- ACM32 航芯
|
||||||
|
- [acm32](acm32) series
|
||||||
|
- APM32 极海
|
||||||
|
- [apm32](apm32) series
|
||||||
|
- 紫芯
|
||||||
|
- [asm9260t](asm9260t)
|
||||||
|
- 博流
|
||||||
|
- [bouffalo_lab](bouffalo_lab) series
|
||||||
|
- 航顺
|
||||||
|
- [hk32](hk32) series
|
||||||
|
- 辉芒微
|
||||||
|
- [ft32](ft32) series
|
||||||
|
- 华芯微特
|
||||||
|
- [synwit](synwit) series
|
||||||
|
- 龙芯
|
||||||
|
- [loongson](loongson) series
|
||||||
|
- 中科蓝讯
|
||||||
|
- [bluetrum](bluetrum) series
|
||||||
|
- 易兆微
|
||||||
|
- [yichip](yichip) series
|
||||||
|
- 杭州万高科技
|
||||||
|
- [Vango](Vango) series
|
||||||
|
- 平头哥
|
||||||
|
- [thead-smart](thead-smart)
|
||||||
|
- 复旦微
|
||||||
|
- [fm33lc026](fm33lc026)
|
||||||
|
- 无锡纳瓦特Navota
|
||||||
|
- [nv32f100x](nv32f100x)
|
||||||
|
- 杭州中天微
|
||||||
|
- [ck802](ck802)
|
||||||
|
- 中国航天科技集团
|
||||||
|
- [bm3803](bm3803)
|
||||||
|
- 东南芯
|
||||||
|
- [sep6200](sep6200)
|
||||||
|
- 京微雅格
|
||||||
|
- [CME_M7](CME_M7)
|
||||||
|
- 好钜润 TIKY
|
||||||
|
- [tkm32F499](tkm32F499)
|
38
components/Kconfig
Normal file
38
components/Kconfig
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
menu "RT-Thread Components"
|
||||||
|
|
||||||
|
config RT_USING_COMPONENTS_INIT
|
||||||
|
bool
|
||||||
|
default n
|
||||||
|
|
||||||
|
config RT_USING_USER_MAIN
|
||||||
|
bool
|
||||||
|
default n
|
||||||
|
|
||||||
|
if RT_USING_USER_MAIN
|
||||||
|
config RT_MAIN_THREAD_STACK_SIZE
|
||||||
|
int "Set main thread stack size"
|
||||||
|
default 6144 if ARCH_CPU_64BIT
|
||||||
|
default 2048
|
||||||
|
|
||||||
|
config RT_MAIN_THREAD_PRIORITY
|
||||||
|
int "Set main thread priority"
|
||||||
|
default 4 if RT_THREAD_PRIORITY_8
|
||||||
|
default 10 if RT_THREAD_PRIORITY_32
|
||||||
|
default 85 if RT_THREAD_PRIORITY_256
|
||||||
|
endif
|
||||||
|
|
||||||
|
config RT_USING_LEGACY
|
||||||
|
bool "Support legacy version for compatibility"
|
||||||
|
default n
|
||||||
|
|
||||||
|
source "$RTT_DIR/components/finsh/Kconfig"
|
||||||
|
source "$RTT_DIR/components/dfs/Kconfig"
|
||||||
|
source "$RTT_DIR/components/fal/Kconfig"
|
||||||
|
source "$RTT_DIR/components/lwp/Kconfig"
|
||||||
|
source "$RTT_DIR/components/drivers/Kconfig"
|
||||||
|
source "$RTT_DIR/components/libc/Kconfig"
|
||||||
|
#source "$RTT_DIR/components/net/Kconfig"
|
||||||
|
source "$RTT_DIR/components/utilities/Kconfig"
|
||||||
|
source "$RTT_DIR/components/vbus/Kconfig"
|
||||||
|
|
||||||
|
endmenu
|
17
components/SConscript
Normal file
17
components/SConscript
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# for module compiling
|
||||||
|
import os
|
||||||
|
Import('remove_components')
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
objs = []
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
list = os.listdir(cwd)
|
||||||
|
|
||||||
|
for item in list:
|
||||||
|
if item in remove_components:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
|
||||||
|
objs = objs + SConscript(os.path.join(item, 'SConscript'))
|
||||||
|
|
||||||
|
Return('objs')
|
52
components/dfs/Kconfig
Normal file
52
components/dfs/Kconfig
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
menu "DFS: device virtual file system"
|
||||||
|
|
||||||
|
config RT_USING_DFS
|
||||||
|
bool "DFS: device virtual file system"
|
||||||
|
select RT_USING_MUTEX
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
The device file system is a light weight virtual file system.
|
||||||
|
|
||||||
|
if RT_USING_DFS
|
||||||
|
config DFS_USING_POSIX
|
||||||
|
bool "Using posix-like functions, open/read/write/close"
|
||||||
|
default y
|
||||||
|
|
||||||
|
config DFS_USING_WORKDIR
|
||||||
|
bool "Using working directory"
|
||||||
|
default y
|
||||||
|
|
||||||
|
config RT_USING_DFS_MNTTABLE
|
||||||
|
bool "Using mount table for file system"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
User can use mount table for automatically mount, for example:
|
||||||
|
const struct dfs_mount_tbl mount_table[] =
|
||||||
|
{
|
||||||
|
{"flash0", "/", "elm", 0, 0},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
The mount_table must be terminated with NULL.
|
||||||
|
|
||||||
|
config DFS_FD_MAX
|
||||||
|
int "The maximal number of opened files"
|
||||||
|
default 16
|
||||||
|
|
||||||
|
choice
|
||||||
|
prompt "The version of DFS"
|
||||||
|
default RT_USING_DFS_V1
|
||||||
|
default RT_USING_DFS_V2 if RT_USING_SMART
|
||||||
|
|
||||||
|
config RT_USING_DFS_V1
|
||||||
|
bool "DFS v1.0"
|
||||||
|
|
||||||
|
config RT_USING_DFS_V2
|
||||||
|
bool "DFS v2.0"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
source "$RTT_DIR/components/dfs/dfs_v1/Kconfig"
|
||||||
|
source "$RTT_DIR/components/dfs/dfs_v2/Kconfig"
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
endmenu
|
15
components/dfs/SConscript
Normal file
15
components/dfs/SConscript
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# RT-Thread building script for bridge
|
||||||
|
|
||||||
|
import os
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
objs = []
|
||||||
|
list = os.listdir(cwd)
|
||||||
|
|
||||||
|
for d in list:
|
||||||
|
path = os.path.join(cwd, d)
|
||||||
|
if os.path.isfile(os.path.join(path, 'SConscript')):
|
||||||
|
objs = objs + SConscript(os.path.join(d, 'SConscript'))
|
||||||
|
|
||||||
|
Return('objs')
|
138
components/dfs/dfs_v1/Kconfig
Normal file
138
components/dfs/dfs_v1/Kconfig
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
if RT_USING_DFS_V1
|
||||||
|
config DFS_FILESYSTEMS_MAX
|
||||||
|
int "The maximal number of mounted file system"
|
||||||
|
default 4
|
||||||
|
|
||||||
|
config DFS_FILESYSTEM_TYPES_MAX
|
||||||
|
int "The maximal number of file system type"
|
||||||
|
default 4
|
||||||
|
|
||||||
|
config RT_USING_DFS_ELMFAT
|
||||||
|
bool "Enable elm-chan fatfs"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
FatFs is a generic FAT/exFAT file system module for small embedded systems.
|
||||||
|
|
||||||
|
if RT_USING_DFS_ELMFAT
|
||||||
|
menu "elm-chan's FatFs, Generic FAT Filesystem Module"
|
||||||
|
config RT_DFS_ELM_CODE_PAGE
|
||||||
|
int "OEM code page"
|
||||||
|
default 437
|
||||||
|
|
||||||
|
config RT_DFS_ELM_WORD_ACCESS
|
||||||
|
bool "Using RT_DFS_ELM_WORD_ACCESS"
|
||||||
|
default y
|
||||||
|
|
||||||
|
choice
|
||||||
|
prompt "Support long file name"
|
||||||
|
default RT_DFS_ELM_USE_LFN_3
|
||||||
|
|
||||||
|
config RT_DFS_ELM_USE_LFN_0
|
||||||
|
bool "0: LFN disable"
|
||||||
|
|
||||||
|
config RT_DFS_ELM_USE_LFN_1
|
||||||
|
bool "1: LFN with static LFN working buffer"
|
||||||
|
|
||||||
|
config RT_DFS_ELM_USE_LFN_2
|
||||||
|
bool "2: LFN with dynamic LFN working buffer on the stack"
|
||||||
|
|
||||||
|
config RT_DFS_ELM_USE_LFN_3
|
||||||
|
bool "3: LFN with dynamic LFN working buffer on the heap"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config RT_DFS_ELM_USE_LFN
|
||||||
|
int
|
||||||
|
default 0 if RT_DFS_ELM_USE_LFN_0
|
||||||
|
default 1 if RT_DFS_ELM_USE_LFN_1
|
||||||
|
default 2 if RT_DFS_ELM_USE_LFN_2
|
||||||
|
default 3 if RT_DFS_ELM_USE_LFN_3
|
||||||
|
|
||||||
|
choice
|
||||||
|
prompt "Support unicode for long file name"
|
||||||
|
default RT_DFS_ELM_LFN_UNICODE_0
|
||||||
|
|
||||||
|
config RT_DFS_ELM_LFN_UNICODE_0
|
||||||
|
bool "0: ANSI/OEM in current CP (TCHAR = char)"
|
||||||
|
|
||||||
|
config RT_DFS_ELM_LFN_UNICODE_1
|
||||||
|
bool "1: Unicode in UTF-16 (TCHAR = WCHAR)"
|
||||||
|
|
||||||
|
config RT_DFS_ELM_LFN_UNICODE_2
|
||||||
|
bool "2: Unicode in UTF-8 (TCHAR = char)"
|
||||||
|
|
||||||
|
config RT_DFS_ELM_LFN_UNICODE_3
|
||||||
|
bool "3: Unicode in UTF-32 (TCHAR = DWORD)"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config RT_DFS_ELM_LFN_UNICODE
|
||||||
|
int
|
||||||
|
default 0 if RT_DFS_ELM_LFN_UNICODE_0
|
||||||
|
default 1 if RT_DFS_ELM_LFN_UNICODE_1
|
||||||
|
default 2 if RT_DFS_ELM_LFN_UNICODE_2
|
||||||
|
default 3 if RT_DFS_ELM_LFN_UNICODE_3
|
||||||
|
|
||||||
|
config RT_DFS_ELM_MAX_LFN
|
||||||
|
int "Maximal size of file name length"
|
||||||
|
range 12 255
|
||||||
|
default 255
|
||||||
|
|
||||||
|
config RT_DFS_ELM_DRIVES
|
||||||
|
int "Number of volumes (logical drives) to be used."
|
||||||
|
default 2
|
||||||
|
|
||||||
|
config RT_DFS_ELM_MAX_SECTOR_SIZE
|
||||||
|
int "Maximum sector size to be handled."
|
||||||
|
default 512
|
||||||
|
help
|
||||||
|
If you use some spi nor flash for fatfs, please set this the erase sector size, for example 4096.
|
||||||
|
|
||||||
|
config RT_DFS_ELM_USE_ERASE
|
||||||
|
bool "Enable sector erase feature"
|
||||||
|
default n
|
||||||
|
|
||||||
|
config RT_DFS_ELM_REENTRANT
|
||||||
|
bool "Enable the reentrancy (thread safe) of the FatFs module"
|
||||||
|
default y
|
||||||
|
|
||||||
|
config RT_DFS_ELM_MUTEX_TIMEOUT
|
||||||
|
int "Timeout of thread-safe protection mutex"
|
||||||
|
range 0 1000000
|
||||||
|
default 3000
|
||||||
|
depends on RT_DFS_ELM_REENTRANT
|
||||||
|
endmenu
|
||||||
|
endif
|
||||||
|
|
||||||
|
config RT_USING_DFS_DEVFS
|
||||||
|
bool "Using devfs for device objects"
|
||||||
|
default y
|
||||||
|
|
||||||
|
config RT_USING_DFS_ROMFS
|
||||||
|
bool "Enable ReadOnly file system on flash"
|
||||||
|
default n
|
||||||
|
|
||||||
|
config RT_USING_DFS_CROMFS
|
||||||
|
bool "Enable ReadOnly compressed file system on flash"
|
||||||
|
default n
|
||||||
|
# select PKG_USING_ZLIB
|
||||||
|
|
||||||
|
config RT_USING_DFS_RAMFS
|
||||||
|
bool "Enable RAM file system"
|
||||||
|
select RT_USING_MEMHEAP
|
||||||
|
default n
|
||||||
|
|
||||||
|
config RT_USING_DFS_TMPFS
|
||||||
|
bool "Enable TMP file system"
|
||||||
|
default n
|
||||||
|
|
||||||
|
config RT_USING_DFS_NFS
|
||||||
|
bool "Using NFS v3 client file system"
|
||||||
|
depends on RT_USING_LWIP
|
||||||
|
default n
|
||||||
|
|
||||||
|
if RT_USING_DFS_NFS
|
||||||
|
config RT_NFS_HOST_EXPORT
|
||||||
|
string "NFSv3 host export"
|
||||||
|
default "192.168.1.5:/"
|
||||||
|
endif
|
||||||
|
|
||||||
|
endif
|
25
components/dfs/dfs_v1/SConscript
Normal file
25
components/dfs/dfs_v1/SConscript
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
from building import *
|
||||||
|
import os
|
||||||
|
|
||||||
|
# The set of source files associated with this SConscript file.
|
||||||
|
src = []
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
CPPPATH = [cwd + "/include"]
|
||||||
|
group = []
|
||||||
|
|
||||||
|
if GetDepend('RT_USING_DFS') and not GetDepend('RT_USING_DFS_V2'):
|
||||||
|
src = ['src/dfs.c', 'src/dfs_file.c', 'src/dfs_fs.c']
|
||||||
|
|
||||||
|
if GetDepend('DFS_USING_POSIX'):
|
||||||
|
src += ['src/dfs_posix.c']
|
||||||
|
|
||||||
|
group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS'], CPPPATH = CPPPATH)
|
||||||
|
|
||||||
|
# search in the file system implementation
|
||||||
|
list = os.listdir(cwd)
|
||||||
|
|
||||||
|
for item in list:
|
||||||
|
if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
|
||||||
|
group = group + SConscript(os.path.join(item, 'SConscript'))
|
||||||
|
|
||||||
|
Return('group')
|
4
components/dfs/dfs_v1/filesystems/.ignore_format.yml
Normal file
4
components/dfs/dfs_v1/filesystems/.ignore_format.yml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# files format check exclude path, please follow the instructions below to modify;
|
||||||
|
|
||||||
|
dir_path:
|
||||||
|
- elmfat
|
15
components/dfs/dfs_v1/filesystems/SConscript
Normal file
15
components/dfs/dfs_v1/filesystems/SConscript
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# RT-Thread building script for bridge
|
||||||
|
|
||||||
|
import os
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
objs = []
|
||||||
|
list = os.listdir(cwd)
|
||||||
|
|
||||||
|
for d in list:
|
||||||
|
path = os.path.join(cwd, d)
|
||||||
|
if os.path.isfile(os.path.join(path, 'SConscript')):
|
||||||
|
objs = objs + SConscript(os.path.join(d, 'SConscript'))
|
||||||
|
|
||||||
|
Return('objs')
|
11
components/dfs/dfs_v1/filesystems/cromfs/SConscript
Normal file
11
components/dfs/dfs_v1/filesystems/cromfs/SConscript
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# RT-Thread building script for component
|
||||||
|
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
src = Glob('*.c')
|
||||||
|
CPPPATH = [cwd]
|
||||||
|
|
||||||
|
group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS','RT_USING_DFS_CROMFS'], CPPPATH = CPPPATH)
|
||||||
|
|
||||||
|
Return('group')
|
1170
components/dfs/dfs_v1/filesystems/cromfs/dfs_cromfs.c
Normal file
1170
components/dfs/dfs_v1/filesystems/cromfs/dfs_cromfs.c
Normal file
File diff suppressed because it is too large
Load diff
16
components/dfs/dfs_v1/filesystems/cromfs/dfs_cromfs.h
Normal file
16
components/dfs/dfs_v1/filesystems/cromfs/dfs_cromfs.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2020, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2020/08/21 ShaoJinchun firset version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DFS_CROMFS_H__
|
||||||
|
#define __DFS_CROMFS_H__
|
||||||
|
|
||||||
|
int dfs_cromfs_init(void);
|
||||||
|
|
||||||
|
#endif /*__DFS_CROMFS_H__*/
|
11
components/dfs/dfs_v1/filesystems/devfs/SConscript
Normal file
11
components/dfs/dfs_v1/filesystems/devfs/SConscript
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# RT-Thread building script for component
|
||||||
|
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
src = Glob('*.c')
|
||||||
|
CPPPATH = [cwd]
|
||||||
|
|
||||||
|
group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS', 'RT_USING_DFS_DEVFS'], CPPPATH = CPPPATH)
|
||||||
|
|
||||||
|
Return('group')
|
416
components/dfs/dfs_v1/filesystems/devfs/devfs.c
Normal file
416
components/dfs/dfs_v1/filesystems/devfs/devfs.c
Normal file
|
@ -0,0 +1,416 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2018-02-11 Bernard Ignore O_CREAT flag in open.
|
||||||
|
*/
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rtdevice.h>
|
||||||
|
|
||||||
|
#include <dfs.h>
|
||||||
|
#include <dfs_fs.h>
|
||||||
|
#include <dfs_file.h>
|
||||||
|
|
||||||
|
#include "devfs.h"
|
||||||
|
|
||||||
|
struct device_dirent
|
||||||
|
{
|
||||||
|
rt_device_t *devices;
|
||||||
|
rt_uint16_t read_index;
|
||||||
|
rt_uint16_t device_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
int dfs_device_fs_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data)
|
||||||
|
{
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_device_fs_statfs(struct dfs_filesystem *fs, struct statfs *buf)
|
||||||
|
{
|
||||||
|
buf->f_bsize = 512;
|
||||||
|
buf->f_blocks = 2048 * 64; // 64M
|
||||||
|
buf->f_bfree = buf->f_blocks;
|
||||||
|
buf->f_bavail = buf->f_bfree;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_device_fs_ioctl(struct dfs_file *file, int cmd, void *args)
|
||||||
|
{
|
||||||
|
rt_err_t result;
|
||||||
|
rt_device_t dev_id;
|
||||||
|
|
||||||
|
RT_ASSERT(file != RT_NULL);
|
||||||
|
|
||||||
|
/* get device handler */
|
||||||
|
dev_id = (rt_device_t)file->vnode->data;
|
||||||
|
RT_ASSERT(dev_id != RT_NULL);
|
||||||
|
|
||||||
|
if ((file->vnode->path[0] == '/') && (file->vnode->path[1] == '\0'))
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
|
||||||
|
/* close device handler */
|
||||||
|
result = rt_device_control(dev_id, cmd, args);
|
||||||
|
if (result == RT_EOK)
|
||||||
|
return RT_EOK;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_device_fs_read(struct dfs_file *file, void *buf, size_t count)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
rt_device_t dev_id;
|
||||||
|
|
||||||
|
RT_ASSERT(file != RT_NULL);
|
||||||
|
|
||||||
|
/* get device handler */
|
||||||
|
dev_id = (rt_device_t)file->vnode->data;
|
||||||
|
RT_ASSERT(dev_id != RT_NULL);
|
||||||
|
|
||||||
|
if ((file->vnode->path[0] == '/') && (file->vnode->path[1] == '\0'))
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
|
||||||
|
/* read device data */
|
||||||
|
result = rt_device_read(dev_id, file->pos, buf, count);
|
||||||
|
file->pos += result;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_device_fs_write(struct dfs_file *file, const void *buf, size_t count)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
rt_device_t dev_id;
|
||||||
|
|
||||||
|
RT_ASSERT(file != RT_NULL);
|
||||||
|
|
||||||
|
/* get device handler */
|
||||||
|
dev_id = (rt_device_t)file->vnode->data;
|
||||||
|
RT_ASSERT(dev_id != RT_NULL);
|
||||||
|
|
||||||
|
if ((file->vnode->path[0] == '/') && (file->vnode->path[1] == '\0'))
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
|
||||||
|
/* read device data */
|
||||||
|
result = rt_device_write(dev_id, file->pos, buf, count);
|
||||||
|
file->pos += result;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_device_fs_close(struct dfs_file *file)
|
||||||
|
{
|
||||||
|
rt_err_t result;
|
||||||
|
rt_device_t dev_id;
|
||||||
|
|
||||||
|
RT_ASSERT(file != RT_NULL);
|
||||||
|
RT_ASSERT(file->vnode->ref_count > 0);
|
||||||
|
|
||||||
|
if (file->vnode->ref_count > 1)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file->vnode->type == FT_DIRECTORY && (file->vnode->path[0] == '/') && (file->vnode->path[1] == '\0'))
|
||||||
|
{
|
||||||
|
struct device_dirent *root_dirent;
|
||||||
|
|
||||||
|
root_dirent = (struct device_dirent *)file->vnode->data;
|
||||||
|
RT_ASSERT(root_dirent != RT_NULL);
|
||||||
|
|
||||||
|
/* release dirent */
|
||||||
|
rt_free(root_dirent);
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get device handler */
|
||||||
|
dev_id = (rt_device_t)file->vnode->data;
|
||||||
|
RT_ASSERT(dev_id != RT_NULL);
|
||||||
|
|
||||||
|
/* close device handler */
|
||||||
|
result = rt_device_close(dev_id);
|
||||||
|
if (result == RT_EOK)
|
||||||
|
{
|
||||||
|
file->vnode->data = RT_NULL;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_device_fs_open(struct dfs_file *file)
|
||||||
|
{
|
||||||
|
rt_err_t result;
|
||||||
|
rt_device_t device;
|
||||||
|
|
||||||
|
RT_ASSERT(file->vnode->ref_count > 0);
|
||||||
|
if (file->vnode->ref_count > 1)
|
||||||
|
{
|
||||||
|
file->pos = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* open root directory */
|
||||||
|
if ((file->vnode->path[0] == '/') && (file->vnode->path[1] == '\0') &&
|
||||||
|
(file->flags & O_DIRECTORY))
|
||||||
|
{
|
||||||
|
struct rt_object *object;
|
||||||
|
struct rt_list_node *node;
|
||||||
|
struct rt_object_information *information;
|
||||||
|
struct device_dirent *root_dirent;
|
||||||
|
rt_uint32_t count = 0;
|
||||||
|
|
||||||
|
/* lock scheduler */
|
||||||
|
rt_enter_critical();
|
||||||
|
|
||||||
|
/* traverse device object */
|
||||||
|
information = rt_object_get_information(RT_Object_Class_Device);
|
||||||
|
RT_ASSERT(information != RT_NULL);
|
||||||
|
for (node = information->object_list.next; node != &(information->object_list); node = node->next)
|
||||||
|
{
|
||||||
|
count ++;
|
||||||
|
}
|
||||||
|
rt_exit_critical();
|
||||||
|
|
||||||
|
root_dirent = (struct device_dirent *)rt_malloc(sizeof(struct device_dirent) +
|
||||||
|
count * sizeof(rt_device_t));
|
||||||
|
if (root_dirent != RT_NULL)
|
||||||
|
{
|
||||||
|
/* lock scheduler */
|
||||||
|
rt_enter_critical();
|
||||||
|
|
||||||
|
root_dirent->devices = (rt_device_t *)(root_dirent + 1);
|
||||||
|
root_dirent->read_index = 0;
|
||||||
|
root_dirent->device_count = count;
|
||||||
|
count = 0;
|
||||||
|
/* get all device node */
|
||||||
|
for (node = information->object_list.next; node != &(information->object_list); node = node->next)
|
||||||
|
{
|
||||||
|
/* avoid memory write through */
|
||||||
|
if (count == root_dirent->device_count)
|
||||||
|
{
|
||||||
|
rt_kprintf("warning: There are newly added devices that are not displayed!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
object = rt_list_entry(node, struct rt_object, list);
|
||||||
|
root_dirent->devices[count] = (rt_device_t)object;
|
||||||
|
count ++;
|
||||||
|
}
|
||||||
|
rt_exit_critical();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set data */
|
||||||
|
file->vnode->data = root_dirent;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
#ifdef RT_USING_DEV_BUS
|
||||||
|
else if (file->flags & O_CREAT)
|
||||||
|
{
|
||||||
|
if (!(file->flags & O_DIRECTORY))
|
||||||
|
{
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
/* regester bus device */
|
||||||
|
if (rt_device_bus_create(&file->vnode->path[1], 0) == RT_NULL)
|
||||||
|
{
|
||||||
|
return -EEXIST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
device = rt_device_find(&file->vnode->path[1]);
|
||||||
|
if (device == RT_NULL)
|
||||||
|
{
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RT_USING_POSIX_DEVIO
|
||||||
|
if (device->fops)
|
||||||
|
{
|
||||||
|
/* use device fops */
|
||||||
|
file->vnode->fops = device->fops;
|
||||||
|
file->vnode->data = (void *)device;
|
||||||
|
|
||||||
|
/* use fops */
|
||||||
|
if (file->vnode->fops->open)
|
||||||
|
{
|
||||||
|
result = file->vnode->fops->open(file);
|
||||||
|
if (result == RT_EOK || result == -RT_ENOSYS)
|
||||||
|
{
|
||||||
|
file->vnode->type = FT_DEVICE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif /* RT_USING_POSIX_DEVIO */
|
||||||
|
{
|
||||||
|
result = rt_device_open(device, RT_DEVICE_OFLAG_RDWR);
|
||||||
|
if (result == RT_EOK || result == -RT_ENOSYS)
|
||||||
|
{
|
||||||
|
file->vnode->data = device;
|
||||||
|
file->vnode->type = FT_DEVICE;
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file->vnode->data = RT_NULL;
|
||||||
|
/* open device failed. */
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_device_fs_unlink(struct dfs_filesystem *fs, const char *path)
|
||||||
|
{
|
||||||
|
#ifdef RT_USING_DEV_BUS
|
||||||
|
rt_device_t dev_id;
|
||||||
|
|
||||||
|
dev_id = rt_device_find(&path[1]);
|
||||||
|
if (dev_id == RT_NULL)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (dev_id->type != RT_Device_Class_Bus)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
rt_device_bus_destroy(dev_id);
|
||||||
|
#endif
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_device_fs_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
|
||||||
|
{
|
||||||
|
/* stat root directory */
|
||||||
|
if ((path[0] == '/') && (path[1] == '\0'))
|
||||||
|
{
|
||||||
|
st->st_dev = 0;
|
||||||
|
|
||||||
|
st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
|
||||||
|
S_IWUSR | S_IWGRP | S_IWOTH;
|
||||||
|
st->st_mode &= ~S_IFREG;
|
||||||
|
st->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
||||||
|
|
||||||
|
st->st_size = 0;
|
||||||
|
st->st_mtime = 0;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_device_t dev_id;
|
||||||
|
|
||||||
|
dev_id = rt_device_find(&path[1]);
|
||||||
|
if (dev_id != RT_NULL)
|
||||||
|
{
|
||||||
|
st->st_dev = 0;
|
||||||
|
|
||||||
|
st->st_mode = S_IRUSR | S_IRGRP | S_IROTH |
|
||||||
|
S_IWUSR | S_IWGRP | S_IWOTH;
|
||||||
|
|
||||||
|
if (dev_id->type == RT_Device_Class_Char)
|
||||||
|
st->st_mode |= S_IFCHR;
|
||||||
|
else if (dev_id->type == RT_Device_Class_Block)
|
||||||
|
st->st_mode |= S_IFBLK;
|
||||||
|
else if (dev_id->type == RT_Device_Class_Pipe)
|
||||||
|
st->st_mode |= S_IFIFO;
|
||||||
|
else if (dev_id->type == RT_Device_Class_Bus)
|
||||||
|
st->st_mode |= S_IFDIR;
|
||||||
|
else
|
||||||
|
st->st_mode |= S_IFREG;
|
||||||
|
|
||||||
|
st->st_size = 0;
|
||||||
|
st->st_mtime = 0;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_device_fs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count)
|
||||||
|
{
|
||||||
|
rt_uint32_t index;
|
||||||
|
rt_object_t object;
|
||||||
|
struct dirent *d;
|
||||||
|
struct device_dirent *root_dirent;
|
||||||
|
|
||||||
|
root_dirent = (struct device_dirent *)file->vnode->data;
|
||||||
|
RT_ASSERT(root_dirent != RT_NULL);
|
||||||
|
|
||||||
|
/* make integer count */
|
||||||
|
count = (count / sizeof(struct dirent));
|
||||||
|
if (count == 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
for (index = 0; index < count && index + root_dirent->read_index < root_dirent->device_count;
|
||||||
|
index ++)
|
||||||
|
{
|
||||||
|
object = (rt_object_t)root_dirent->devices[root_dirent->read_index + index];
|
||||||
|
|
||||||
|
d = dirp + index;
|
||||||
|
if ((((rt_device_t)object)->type) == RT_Device_Class_Bus)
|
||||||
|
{
|
||||||
|
d->d_type = DT_DIR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d->d_type = DT_REG;
|
||||||
|
}
|
||||||
|
d->d_namlen = RT_NAME_MAX;
|
||||||
|
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
|
||||||
|
rt_strncpy(d->d_name, object->name, RT_NAME_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
root_dirent->read_index += index;
|
||||||
|
|
||||||
|
return index * sizeof(struct dirent);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dfs_device_fs_poll(struct dfs_file *fd, struct rt_pollreq *req)
|
||||||
|
{
|
||||||
|
int mask = 0;
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dfs_file_ops _device_fops =
|
||||||
|
{
|
||||||
|
dfs_device_fs_open,
|
||||||
|
dfs_device_fs_close,
|
||||||
|
dfs_device_fs_ioctl,
|
||||||
|
dfs_device_fs_read,
|
||||||
|
dfs_device_fs_write,
|
||||||
|
RT_NULL, /* flush */
|
||||||
|
RT_NULL, /* lseek */
|
||||||
|
dfs_device_fs_getdents,
|
||||||
|
dfs_device_fs_poll,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct dfs_filesystem_ops _device_fs =
|
||||||
|
{
|
||||||
|
"devfs",
|
||||||
|
DFS_FS_FLAG_DEFAULT,
|
||||||
|
&_device_fops,
|
||||||
|
dfs_device_fs_mount,
|
||||||
|
RT_NULL, /*unmount*/
|
||||||
|
RT_NULL, /*mkfs*/
|
||||||
|
dfs_device_fs_statfs,
|
||||||
|
dfs_device_fs_unlink,
|
||||||
|
dfs_device_fs_stat,
|
||||||
|
RT_NULL, /*rename*/
|
||||||
|
};
|
||||||
|
|
||||||
|
int devfs_init(void)
|
||||||
|
{
|
||||||
|
/* register device file system */
|
||||||
|
dfs_register(&_device_fs);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
17
components/dfs/dfs_v1/filesystems/devfs/devfs.h
Normal file
17
components/dfs/dfs_v1/filesystems/devfs/devfs.h
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DEVICE_FS_H__
|
||||||
|
#define __DEVICE_FS_H__
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
int devfs_init(void);
|
||||||
|
|
||||||
|
#endif
|
10
components/dfs/dfs_v1/filesystems/elmfat/.ignore_format.yml
Normal file
10
components/dfs/dfs_v1/filesystems/elmfat/.ignore_format.yml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# files format check exclude path, please follow the instructions below to modify;
|
||||||
|
# If you need to exclude an entire folder, add the folder path in dir_path;
|
||||||
|
# If you need to exclude a file, add the path to the file in file_path.
|
||||||
|
|
||||||
|
file_path:
|
||||||
|
- diskio.h
|
||||||
|
- ff.c
|
||||||
|
- ff.h
|
||||||
|
- ffconf.h
|
||||||
|
- ffunicode.c
|
359
components/dfs/dfs_v1/filesystems/elmfat/00history.txt
Normal file
359
components/dfs/dfs_v1/filesystems/elmfat/00history.txt
Normal file
|
@ -0,0 +1,359 @@
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
Revision history of FatFs module
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
R0.00 (February 26, 2006)
|
||||||
|
|
||||||
|
Prototype.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.01 (April 29, 2006)
|
||||||
|
|
||||||
|
The first release.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.02 (June 01, 2006)
|
||||||
|
|
||||||
|
Added FAT12 support.
|
||||||
|
Removed unbuffered mode.
|
||||||
|
Fixed a problem on small (<32M) partition.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.02a (June 10, 2006)
|
||||||
|
|
||||||
|
Added a configuration option (_FS_MINIMUM).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.03 (September 22, 2006)
|
||||||
|
|
||||||
|
Added f_rename().
|
||||||
|
Changed option _FS_MINIMUM to _FS_MINIMIZE.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.03a (December 11, 2006)
|
||||||
|
|
||||||
|
Improved cluster scan algorithm to write files fast.
|
||||||
|
Fixed f_mkdir() creates incorrect directory on FAT32.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.04 (February 04, 2007)
|
||||||
|
|
||||||
|
Added f_mkfs().
|
||||||
|
Supported multiple drive system.
|
||||||
|
Changed some interfaces for multiple drive system.
|
||||||
|
Changed f_mountdrv() to f_mount().
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.04a (April 01, 2007)
|
||||||
|
|
||||||
|
Supported multiple partitions on a physical drive.
|
||||||
|
Added a capability of extending file size to f_lseek().
|
||||||
|
Added minimization level 3.
|
||||||
|
Fixed an endian sensitive code in f_mkfs().
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.04b (May 05, 2007)
|
||||||
|
|
||||||
|
Added a configuration option _USE_NTFLAG.
|
||||||
|
Added FSINFO support.
|
||||||
|
Fixed DBCS name can result FR_INVALID_NAME.
|
||||||
|
Fixed short seek (<= csize) collapses the file object.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.05 (August 25, 2007)
|
||||||
|
|
||||||
|
Changed arguments of f_read(), f_write() and f_mkfs().
|
||||||
|
Fixed f_mkfs() on FAT32 creates incorrect FSINFO.
|
||||||
|
Fixed f_mkdir() on FAT32 creates incorrect directory.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.05a (February 03, 2008)
|
||||||
|
|
||||||
|
Added f_truncate() and f_utime().
|
||||||
|
Fixed off by one error at FAT sub-type determination.
|
||||||
|
Fixed btr in f_read() can be mistruncated.
|
||||||
|
Fixed cached sector is not flushed when create and close without write.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.06 (April 01, 2008)
|
||||||
|
|
||||||
|
Added fputc(), fputs(), fprintf() and fgets().
|
||||||
|
Improved performance of f_lseek() on moving to the same or following cluster.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.07 (April 01, 2009)
|
||||||
|
|
||||||
|
Merged Tiny-FatFs as a configuration option. (_FS_TINY)
|
||||||
|
Added long file name feature. (_USE_LFN)
|
||||||
|
Added multiple code page feature. (_CODE_PAGE)
|
||||||
|
Added re-entrancy for multitask operation. (_FS_REENTRANT)
|
||||||
|
Added auto cluster size selection to f_mkfs().
|
||||||
|
Added rewind option to f_readdir().
|
||||||
|
Changed result code of critical errors.
|
||||||
|
Renamed string functions to avoid name collision.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.07a (April 14, 2009)
|
||||||
|
|
||||||
|
Septemberarated out OS dependent code on reentrant cfg.
|
||||||
|
Added multiple sector size feature.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.07c (June 21, 2009)
|
||||||
|
|
||||||
|
Fixed f_unlink() can return FR_OK on error.
|
||||||
|
Fixed wrong cache control in f_lseek().
|
||||||
|
Added relative path feature.
|
||||||
|
Added f_chdir() and f_chdrive().
|
||||||
|
Added proper case conversion to extended character.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.07e (November 03, 2009)
|
||||||
|
|
||||||
|
Septemberarated out configuration options from ff.h to ffconf.h.
|
||||||
|
Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH.
|
||||||
|
Fixed name matching error on the 13 character boundary.
|
||||||
|
Added a configuration option, _LFN_UNICODE.
|
||||||
|
Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.08 (May 15, 2010)
|
||||||
|
|
||||||
|
Added a memory configuration option. (_USE_LFN = 3)
|
||||||
|
Added file lock feature. (_FS_SHARE)
|
||||||
|
Added fast seek feature. (_USE_FASTSEEK)
|
||||||
|
Changed some types on the API, XCHAR->TCHAR.
|
||||||
|
Changed .fname in the FILINFO structure on Unicode cfg.
|
||||||
|
String functions support UTF-8 encoding files on Unicode cfg.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.08a (August 16, 2010)
|
||||||
|
|
||||||
|
Added f_getcwd(). (_FS_RPATH = 2)
|
||||||
|
Added sector erase feature. (_USE_ERASE)
|
||||||
|
Moved file lock semaphore table from fs object to the bss.
|
||||||
|
Fixed f_mkfs() creates wrong FAT32 volume.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.08b (January 15, 2011)
|
||||||
|
|
||||||
|
Fast seek feature is also applied to f_read() and f_write().
|
||||||
|
f_lseek() reports required table size on creating CLMP.
|
||||||
|
Extended format syntax of f_printf().
|
||||||
|
Ignores duplicated directory separators in given path name.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.09 (September 06, 2011)
|
||||||
|
|
||||||
|
f_mkfs() supports multiple partition to complete the multiple partition feature.
|
||||||
|
Added f_fdisk().
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.09a (August 27, 2012)
|
||||||
|
|
||||||
|
Changed f_open() and f_opendir() reject null object pointer to avoid crash.
|
||||||
|
Changed option name _FS_SHARE to _FS_LOCK.
|
||||||
|
Fixed assertion failure due to OS/2 EA on FAT12/16 volume.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.09b (January 24, 2013)
|
||||||
|
|
||||||
|
Added f_setlabel() and f_getlabel().
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.10 (October 02, 2013)
|
||||||
|
|
||||||
|
Added selection of character encoding on the file. (_STRF_ENCODE)
|
||||||
|
Added f_closedir().
|
||||||
|
Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
|
||||||
|
Added forced mount feature with changes of f_mount().
|
||||||
|
Improved behavior of volume auto detection.
|
||||||
|
Improved write throughput of f_puts() and f_printf().
|
||||||
|
Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
|
||||||
|
Fixed f_write() can be truncated when the file size is close to 4GB.
|
||||||
|
Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect value on error.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.10a (January 15, 2014)
|
||||||
|
|
||||||
|
Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
|
||||||
|
Added a configuration option of minimum sector size. (_MIN_SS)
|
||||||
|
2nd argument of f_rename() can have a drive number and it will be ignored.
|
||||||
|
Fixed f_mount() with forced mount fails when drive number is >= 1. (appeared at R0.10)
|
||||||
|
Fixed f_close() invalidates the file object without volume lock.
|
||||||
|
Fixed f_closedir() returns but the volume lock is left acquired. (appeared at R0.10)
|
||||||
|
Fixed creation of an entry with LFN fails on too many SFN collisions. (appeared at R0.07)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.10b (May 19, 2014)
|
||||||
|
|
||||||
|
Fixed a hard error in the disk I/O layer can collapse the directory entry.
|
||||||
|
Fixed LFN entry is not deleted when delete/rename an object with lossy converted SFN. (appeared at R0.07)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.10c (November 09, 2014)
|
||||||
|
|
||||||
|
Added a configuration option for the platforms without RTC. (_FS_NORTC)
|
||||||
|
Changed option name _USE_ERASE to _USE_TRIM.
|
||||||
|
Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). (appeared at R0.09b)
|
||||||
|
Fixed a potential problem of FAT access that can appear on disk error.
|
||||||
|
Fixed null pointer dereference on attempting to delete the root direcotry. (appeared at R0.08)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.11 (February 09, 2015)
|
||||||
|
|
||||||
|
Added f_findfirst(), f_findnext() and f_findclose(). (_USE_FIND)
|
||||||
|
Fixed f_unlink() does not remove cluster chain of the file. (appeared at R0.10c)
|
||||||
|
Fixed _FS_NORTC option does not work properly. (appeared at R0.10c)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.11a (September 05, 2015)
|
||||||
|
|
||||||
|
Fixed wrong media change can lead a deadlock at thread-safe configuration.
|
||||||
|
Added code page 771, 860, 861, 863, 864, 865 and 869. (_CODE_PAGE)
|
||||||
|
Removed some code pages actually not exist on the standard systems. (_CODE_PAGE)
|
||||||
|
Fixed errors in the case conversion teble of code page 437 and 850 (ff.c).
|
||||||
|
Fixed errors in the case conversion teble of Unicode (cc*.c).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.12 (April 12, 2016)
|
||||||
|
|
||||||
|
Added support for exFAT file system. (_FS_EXFAT)
|
||||||
|
Added f_expand(). (_USE_EXPAND)
|
||||||
|
Changed some members in FINFO structure and behavior of f_readdir().
|
||||||
|
Added an option _USE_CHMOD.
|
||||||
|
Removed an option _WORD_ACCESS.
|
||||||
|
Fixed errors in the case conversion table of Unicode (cc*.c).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.12a (July 10, 2016)
|
||||||
|
|
||||||
|
Added support for creating exFAT volume with some changes of f_mkfs().
|
||||||
|
Added a file open method FA_OPEN_APPEND. An f_lseek() following f_open() is no longer needed.
|
||||||
|
f_forward() is available regardless of _FS_TINY.
|
||||||
|
Fixed f_mkfs() creates wrong volume. (appeared at R0.12)
|
||||||
|
Fixed wrong memory read in create_name(). (appeared at R0.12)
|
||||||
|
Fixed compilation fails at some configurations, _USE_FASTSEEK and _USE_FORWARD.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.12b (September 04, 2016)
|
||||||
|
|
||||||
|
Made f_rename() be able to rename objects with the same name but case.
|
||||||
|
Fixed an error in the case conversion teble of code page 866. (ff.c)
|
||||||
|
Fixed writing data is truncated at the file offset 4GiB on the exFAT volume. (appeared at R0.12)
|
||||||
|
Fixed creating a file in the root directory of exFAT volume can fail. (appeared at R0.12)
|
||||||
|
Fixed f_mkfs() creating exFAT volume with too small cluster size can collapse unallocated memory. (appeared at R0.12)
|
||||||
|
Fixed wrong object name can be returned when read directory at Unicode cfg. (appeared at R0.12)
|
||||||
|
Fixed large file allocation/removing on the exFAT volume collapses allocation bitmap. (appeared at R0.12)
|
||||||
|
Fixed some internal errors in f_expand() and f_lseek(). (appeared at R0.12)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.12c (March 04, 2017)
|
||||||
|
|
||||||
|
Improved write throughput at the fragmented file on the exFAT volume.
|
||||||
|
Made memory usage for exFAT be able to be reduced as decreasing _MAX_LFN.
|
||||||
|
Fixed successive f_getfree() can return wrong count on the FAT12/16 volume. (appeared at R0.12)
|
||||||
|
Fixed configuration option _VOLUMES cannot be set 10. (appeared at R0.10c)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.13 (May 21, 2017)
|
||||||
|
|
||||||
|
Changed heading character of configuration keywords "_" to "FF_".
|
||||||
|
Removed ASCII-only configuration, FF_CODE_PAGE = 1. Use FF_CODE_PAGE = 437 instead.
|
||||||
|
Added f_setcp(), run-time code page configuration. (FF_CODE_PAGE = 0)
|
||||||
|
Improved cluster allocation time on stretch a deep buried cluster chain.
|
||||||
|
Improved processing time of f_mkdir() with large cluster size by using FF_USE_LFN = 3.
|
||||||
|
Improved NoFatChain flag of the fragmented file to be set after it is truncated and got contiguous.
|
||||||
|
Fixed archive attribute is left not set when a file on the exFAT volume is renamed. (appeared at R0.12)
|
||||||
|
Fixed exFAT FAT entry can be collapsed when write or lseek operation to the existing file is done. (appeared at R0.12c)
|
||||||
|
Fixed creating a file can fail when a new cluster allocation to the exFAT directory occures. (appeared at R0.12c)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.13a (October 14, 2017)
|
||||||
|
|
||||||
|
Added support for UTF-8 encoding on the API. (FF_LFN_UNICODE = 2)
|
||||||
|
Added options for file name output buffer. (FF_LFN_BUF, FF_SFN_BUF).
|
||||||
|
Added dynamic memory allocation option for working buffer of f_mkfs() and f_fdisk().
|
||||||
|
Fixed f_fdisk() and f_mkfs() create the partition table with wrong CHS parameters. (appeared at R0.09)
|
||||||
|
Fixed f_unlink() can cause lost clusters at fragmented file on the exFAT volume. (appeared at R0.12c)
|
||||||
|
Fixed f_setlabel() rejects some valid characters for exFAT volume. (appeared at R0.12)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.13b (April 07, 2018)
|
||||||
|
|
||||||
|
Added support for UTF-32 encoding on the API. (FF_LFN_UNICODE = 3)
|
||||||
|
Added support for Unix style volume ID. (FF_STR_VOLUME_ID = 2)
|
||||||
|
Fixed accesing any object on the exFAT root directory beyond the cluster boundary can fail. (appeared at R0.12c)
|
||||||
|
Fixed f_setlabel() does not reject some invalid characters. (appeared at R0.09b)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.13c (October 14, 2018)
|
||||||
|
Supported stdint.h for C99 and later. (integer.h was included in ff.h)
|
||||||
|
Fixed reading a directory gets infinite loop when the last directory entry is not empty. (appeared at R0.12)
|
||||||
|
Fixed creating a sub-directory in the fragmented sub-directory on the exFAT volume collapses FAT chain of the parent directory. (appeared at R0.12)
|
||||||
|
Fixed f_getcwd() cause output buffer overrun when the buffer has a valid drive number. (appeared at R0.13b)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.14 (October 14, 2019)
|
||||||
|
Added support for 64-bit LBA and GUID partition table (FF_LBA64 = 1)
|
||||||
|
Changed some API functions, f_mkfs() and f_fdisk().
|
||||||
|
Fixed f_open() function cannot find the file with file name in length of FF_MAX_LFN characters.
|
||||||
|
Fixed f_readdir() function cannot retrieve long file names in length of FF_MAX_LFN - 1 characters.
|
||||||
|
Fixed f_readdir() function returns file names with wrong case conversion. (appeared at R0.12)
|
||||||
|
Fixed f_mkfs() function can fail to create exFAT volume in the second partition. (appeared at R0.12)
|
||||||
|
|
||||||
|
|
||||||
|
R0.14a (December 5, 2020)
|
||||||
|
Limited number of recursive calls in f_findnext().
|
||||||
|
Fixed old floppy disks formatted with MS-DOS 2.x and 3.x cannot be mounted.
|
||||||
|
Fixed some compiler warnings.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.14b (April 17, 2021)
|
||||||
|
Made FatFs uses standard library <string.h> for copy, compare and search instead of built-in string functions.
|
||||||
|
Added support for long long integer and floating point to f_printf(). (FF_STRF_LLI and FF_STRF_FP)
|
||||||
|
Made path name parser ignore the terminating separator to allow "dir/".
|
||||||
|
Improved the compatibility in Unix style path name feature.
|
||||||
|
Fixed the file gets dead-locked when f_open() failed with some conditions. (appeared at R0.12a)
|
||||||
|
Fixed f_mkfs() can create wrong exFAT volume due to a timing dependent error. (appeared at R0.12)
|
||||||
|
Fixed code page 855 cannot be set by f_setcp().
|
||||||
|
Fixed some compiler warnings.
|
||||||
|
|
||||||
|
|
21
components/dfs/dfs_v1/filesystems/elmfat/00readme.txt
Normal file
21
components/dfs/dfs_v1/filesystems/elmfat/00readme.txt
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
FatFs Module Source Files R0.14b
|
||||||
|
|
||||||
|
|
||||||
|
FILES
|
||||||
|
|
||||||
|
00readme.txt This file.
|
||||||
|
00history.txt Revision history.
|
||||||
|
ff.c FatFs module.
|
||||||
|
ffconf.h Configuration file of FatFs module.
|
||||||
|
ff.h Common include file for FatFs and application module.
|
||||||
|
diskio.h Common include file for FatFs and disk I/O module.
|
||||||
|
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
|
||||||
|
ffunicode.c Optional Unicode utility functions.
|
||||||
|
ffsystem.c An example of optional O/S related functions.
|
||||||
|
|
||||||
|
|
||||||
|
Low level disk I/O module is not included in this archive because the FatFs
|
||||||
|
module is only a generic file system layer and it does not depend on any specific
|
||||||
|
storage device. You need to provide a low level disk I/O module written to
|
||||||
|
control the storage device that attached to the target system.
|
||||||
|
|
11
components/dfs/dfs_v1/filesystems/elmfat/SConscript
Normal file
11
components/dfs/dfs_v1/filesystems/elmfat/SConscript
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# RT-Thread building script for component
|
||||||
|
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
src = Glob('*.c')
|
||||||
|
CPPPATH = [cwd]
|
||||||
|
|
||||||
|
group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS', 'RT_USING_DFS_ELMFAT'], CPPPATH = CPPPATH)
|
||||||
|
|
||||||
|
Return('group')
|
1058
components/dfs/dfs_v1/filesystems/elmfat/dfs_elm.c
Normal file
1058
components/dfs/dfs_v1/filesystems/elmfat/dfs_elm.c
Normal file
File diff suppressed because it is too large
Load diff
24
components/dfs/dfs_v1/filesystems/elmfat/dfs_elm.h
Normal file
24
components/dfs/dfs_v1/filesystems/elmfat/dfs_elm.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2010-02-06 Bernard Add elm_init function declaration
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DFS_ELM_H__
|
||||||
|
#define __DFS_ELM_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int elm_init(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
77
components/dfs/dfs_v1/filesystems/elmfat/diskio.h
Normal file
77
components/dfs/dfs_v1/filesystems/elmfat/diskio.h
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
/*-----------------------------------------------------------------------/
|
||||||
|
/ Low level disk interface modlue include file (C)ChaN, 2019 /
|
||||||
|
/-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef _DISKIO_DEFINED
|
||||||
|
#define _DISKIO_DEFINED
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Status of Disk Functions */
|
||||||
|
typedef BYTE DSTATUS;
|
||||||
|
|
||||||
|
/* Results of Disk Functions */
|
||||||
|
typedef enum {
|
||||||
|
RES_OK = 0, /* 0: Successful */
|
||||||
|
RES_ERROR, /* 1: R/W Error */
|
||||||
|
RES_WRPRT, /* 2: Write Protected */
|
||||||
|
RES_NOTRDY, /* 3: Not Ready */
|
||||||
|
RES_PARERR /* 4: Invalid Parameter */
|
||||||
|
} DRESULT;
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------*/
|
||||||
|
/* Prototypes for disk control functions */
|
||||||
|
|
||||||
|
|
||||||
|
DSTATUS disk_initialize (BYTE pdrv);
|
||||||
|
DSTATUS disk_status (BYTE pdrv);
|
||||||
|
DRESULT disk_read (BYTE pdrv, BYTE* buff, LBA_t sector, UINT count);
|
||||||
|
DRESULT disk_write (BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count);
|
||||||
|
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||||
|
|
||||||
|
|
||||||
|
/* Disk Status Bits (DSTATUS) */
|
||||||
|
|
||||||
|
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||||
|
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||||
|
#define STA_PROTECT 0x04 /* Write protected */
|
||||||
|
|
||||||
|
|
||||||
|
/* Command code for disk_ioctrl fucntion */
|
||||||
|
|
||||||
|
/* Generic command (Used by FatFs) */
|
||||||
|
#define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */
|
||||||
|
#define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */
|
||||||
|
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
|
||||||
|
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
|
||||||
|
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
|
||||||
|
|
||||||
|
/* Generic command (Not used by FatFs) */
|
||||||
|
#define CTRL_POWER 5 /* Get/Set power status */
|
||||||
|
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||||
|
#define CTRL_EJECT 7 /* Eject media */
|
||||||
|
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
||||||
|
|
||||||
|
/* MMC/SDC specific ioctl command */
|
||||||
|
#define MMC_GET_TYPE 10 /* Get card type */
|
||||||
|
#define MMC_GET_CSD 11 /* Get CSD */
|
||||||
|
#define MMC_GET_CID 12 /* Get CID */
|
||||||
|
#define MMC_GET_OCR 13 /* Get OCR */
|
||||||
|
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||||
|
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
|
||||||
|
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
|
||||||
|
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
|
||||||
|
|
||||||
|
/* ATA/CF specific ioctl command */
|
||||||
|
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||||
|
#define ATA_GET_MODEL 21 /* Get model name */
|
||||||
|
#define ATA_GET_SN 22 /* Get serial number */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
7014
components/dfs/dfs_v1/filesystems/elmfat/ff.c
Normal file
7014
components/dfs/dfs_v1/filesystems/elmfat/ff.c
Normal file
File diff suppressed because it is too large
Load diff
424
components/dfs/dfs_v1/filesystems/elmfat/ff.h
Normal file
424
components/dfs/dfs_v1/filesystems/elmfat/ff.h
Normal file
|
@ -0,0 +1,424 @@
|
||||||
|
/*----------------------------------------------------------------------------/
|
||||||
|
/ FatFs - Generic FAT Filesystem module R0.14b /
|
||||||
|
/-----------------------------------------------------------------------------/
|
||||||
|
/
|
||||||
|
/ Copyright (C) 2021, ChaN, all right reserved.
|
||||||
|
/
|
||||||
|
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
||||||
|
/ source and binary forms, with or without modification, are permitted provided
|
||||||
|
/ that the following condition is met:
|
||||||
|
|
||||||
|
/ 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
/ this condition and the following disclaimer.
|
||||||
|
/
|
||||||
|
/ This software is provided by the copyright holder and contributors "AS IS"
|
||||||
|
/ and any warranties related to this software are DISCLAIMED.
|
||||||
|
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
||||||
|
/ by use of this software.
|
||||||
|
/
|
||||||
|
/----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef FF_DEFINED
|
||||||
|
#define FF_DEFINED 86631 /* Revision ID */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include "ffconf.h" /* FatFs configuration options */
|
||||||
|
|
||||||
|
#if FF_DEFINED != FFCONF_DEF
|
||||||
|
#error Wrong configuration file (ffconf.h).
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Integer types used for FatFs API */
|
||||||
|
|
||||||
|
#if defined(_WIN32) /* Windows VC++ (for development only) */
|
||||||
|
#define FF_INTDEF 2
|
||||||
|
#include <windows.h>
|
||||||
|
typedef unsigned __int64 QWORD;
|
||||||
|
#include <float.h>
|
||||||
|
#define isnan(v) _isnan(v)
|
||||||
|
#define isinf(v) (!_finite(v))
|
||||||
|
|
||||||
|
#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */
|
||||||
|
#define FF_INTDEF 2
|
||||||
|
#include <stdint.h>
|
||||||
|
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
|
||||||
|
typedef unsigned char BYTE; /* char must be 8-bit */
|
||||||
|
typedef uint16_t WORD; /* 16-bit unsigned integer */
|
||||||
|
typedef uint32_t DWORD; /* 32-bit unsigned integer */
|
||||||
|
typedef uint64_t QWORD; /* 64-bit unsigned integer */
|
||||||
|
typedef WORD WCHAR; /* UTF-16 character type */
|
||||||
|
|
||||||
|
#else /* Earlier than C99 */
|
||||||
|
#define FF_INTDEF 1
|
||||||
|
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
|
||||||
|
typedef unsigned char BYTE; /* char must be 8-bit */
|
||||||
|
typedef unsigned short WORD; /* 16-bit unsigned integer */
|
||||||
|
typedef unsigned long DWORD; /* 32-bit unsigned integer */
|
||||||
|
typedef WORD WCHAR; /* UTF-16 character type */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Type of file size and LBA variables */
|
||||||
|
|
||||||
|
#if FF_FS_EXFAT
|
||||||
|
#if FF_INTDEF != 2
|
||||||
|
#error exFAT feature wants C99 or later
|
||||||
|
#endif
|
||||||
|
typedef QWORD FSIZE_t;
|
||||||
|
#if FF_LBA64
|
||||||
|
typedef QWORD LBA_t;
|
||||||
|
#else
|
||||||
|
typedef DWORD LBA_t;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if FF_LBA64
|
||||||
|
#error exFAT needs to be enabled when enable 64-bit LBA
|
||||||
|
#endif
|
||||||
|
typedef DWORD FSIZE_t;
|
||||||
|
typedef DWORD LBA_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Type of path name strings on FatFs API (TCHAR) */
|
||||||
|
|
||||||
|
#if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */
|
||||||
|
typedef WCHAR TCHAR;
|
||||||
|
#define _T(x) L ## x
|
||||||
|
#define _TEXT(x) L ## x
|
||||||
|
#elif FF_USE_LFN && FF_LFN_UNICODE == 2 /* Unicode in UTF-8 encoding */
|
||||||
|
typedef char TCHAR;
|
||||||
|
#define _T(x) u8 ## x
|
||||||
|
#define _TEXT(x) u8 ## x
|
||||||
|
#elif FF_USE_LFN && FF_LFN_UNICODE == 3 /* Unicode in UTF-32 encoding */
|
||||||
|
typedef DWORD TCHAR;
|
||||||
|
#define _T(x) U ## x
|
||||||
|
#define _TEXT(x) U ## x
|
||||||
|
#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3)
|
||||||
|
#error Wrong FF_LFN_UNICODE setting
|
||||||
|
#else /* ANSI/OEM code in SBCS/DBCS */
|
||||||
|
typedef char TCHAR;
|
||||||
|
#define _T(x) x
|
||||||
|
#define _TEXT(x) x
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Definitions of volume management */
|
||||||
|
|
||||||
|
#if FF_MULTI_PARTITION /* Multiple partition configuration */
|
||||||
|
typedef struct {
|
||||||
|
BYTE pd; /* Physical drive number */
|
||||||
|
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||||
|
} PARTITION;
|
||||||
|
extern PARTITION VolToPart[]; /* Volume - Partition mapping table */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if FF_STR_VOLUME_ID
|
||||||
|
#ifndef FF_VOLUME_STRS
|
||||||
|
extern const char* VolumeStr[FF_VOLUMES]; /* User defied volume ID */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Filesystem object structure (FATFS) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
BYTE fs_type; /* Filesystem type (0:not mounted) */
|
||||||
|
BYTE pdrv; /* Associated physical drive */
|
||||||
|
BYTE n_fats; /* Number of FATs (1 or 2) */
|
||||||
|
BYTE wflag; /* win[] flag (b0:dirty) */
|
||||||
|
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
|
||||||
|
WORD id; /* Volume mount ID */
|
||||||
|
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||||
|
WORD csize; /* Cluster size [sectors] */
|
||||||
|
#if FF_MAX_SS != FF_MIN_SS
|
||||||
|
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
|
||||||
|
#endif
|
||||||
|
#if FF_USE_LFN
|
||||||
|
WCHAR* lfnbuf; /* LFN working buffer */
|
||||||
|
#endif
|
||||||
|
#if FF_FS_EXFAT
|
||||||
|
BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */
|
||||||
|
#endif
|
||||||
|
#if FF_FS_REENTRANT
|
||||||
|
FF_SYNC_t sobj; /* Identifier of sync object */
|
||||||
|
#endif
|
||||||
|
#if !FF_FS_READONLY
|
||||||
|
DWORD last_clst; /* Last allocated cluster */
|
||||||
|
DWORD free_clst; /* Number of free clusters */
|
||||||
|
#endif
|
||||||
|
#if FF_FS_RPATH
|
||||||
|
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||||
|
#if FF_FS_EXFAT
|
||||||
|
DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */
|
||||||
|
DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */
|
||||||
|
DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
|
||||||
|
DWORD fsize; /* Size of an FAT [sectors] */
|
||||||
|
LBA_t volbase; /* Volume base sector */
|
||||||
|
LBA_t fatbase; /* FAT base sector */
|
||||||
|
LBA_t dirbase; /* Root directory base sector/cluster */
|
||||||
|
LBA_t database; /* Data base sector */
|
||||||
|
#if FF_FS_EXFAT
|
||||||
|
LBA_t bitbase; /* Allocation bitmap base sector */
|
||||||
|
#endif
|
||||||
|
LBA_t winsect; /* Current sector appearing in the win[] */
|
||||||
|
BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||||
|
} FATFS;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Object ID and allocation information (FFOBJID) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FATFS* fs; /* Pointer to the hosting volume of this object */
|
||||||
|
WORD id; /* Hosting volume mount ID */
|
||||||
|
BYTE attr; /* Object attribute */
|
||||||
|
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */
|
||||||
|
DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */
|
||||||
|
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
|
||||||
|
#if FF_FS_EXFAT
|
||||||
|
DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */
|
||||||
|
DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */
|
||||||
|
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
|
||||||
|
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
|
||||||
|
DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */
|
||||||
|
#endif
|
||||||
|
#if FF_FS_LOCK
|
||||||
|
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||||
|
#endif
|
||||||
|
} FFOBJID;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* File object structure (FIL) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
|
||||||
|
BYTE flag; /* File status flags */
|
||||||
|
BYTE err; /* Abort flag (error code) */
|
||||||
|
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
|
||||||
|
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
|
||||||
|
LBA_t sect; /* Sector number appearing in buf[] (0:invalid) */
|
||||||
|
#if !FF_FS_READONLY
|
||||||
|
LBA_t dir_sect; /* Sector number containing the directory entry (not used at exFAT) */
|
||||||
|
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */
|
||||||
|
#endif
|
||||||
|
#if FF_USE_FASTSEEK
|
||||||
|
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
||||||
|
#endif
|
||||||
|
#if !FF_FS_TINY
|
||||||
|
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
|
||||||
|
#endif
|
||||||
|
} FIL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Directory object structure (DIR) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FFOBJID obj; /* Object identifier */
|
||||||
|
DWORD dptr; /* Current read/write offset */
|
||||||
|
DWORD clust; /* Current cluster */
|
||||||
|
LBA_t sect; /* Current sector (0:Read operation has terminated) */
|
||||||
|
BYTE* dir; /* Pointer to the directory item in the win[] */
|
||||||
|
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
|
||||||
|
#if FF_USE_LFN
|
||||||
|
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
|
||||||
|
#endif
|
||||||
|
#if FF_USE_FIND
|
||||||
|
const TCHAR* pat; /* Pointer to the name matching pattern */
|
||||||
|
#endif
|
||||||
|
} DIR;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* File information structure (FILINFO) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FSIZE_t fsize; /* File size */
|
||||||
|
WORD fdate; /* Modified date */
|
||||||
|
WORD ftime; /* Modified time */
|
||||||
|
BYTE fattrib; /* File attribute */
|
||||||
|
#if FF_USE_LFN
|
||||||
|
TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */
|
||||||
|
TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
|
||||||
|
#else
|
||||||
|
TCHAR fname[12 + 1]; /* File name */
|
||||||
|
#endif
|
||||||
|
} FILINFO;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Format parameter structure (MKFS_PARM) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
BYTE fmt; /* Format option (FM_FAT, FM_FAT32, FM_EXFAT and FM_SFD) */
|
||||||
|
BYTE n_fat; /* Number of FATs */
|
||||||
|
UINT align; /* Data area alignment (sector) */
|
||||||
|
UINT n_root; /* Number of root directory entries */
|
||||||
|
DWORD au_size; /* Cluster size (byte) */
|
||||||
|
} MKFS_PARM;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* File function return code (FRESULT) */
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
FR_OK = 0, /* (0) Succeeded */
|
||||||
|
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
|
||||||
|
FR_INT_ERR, /* (2) Assertion failed */
|
||||||
|
FR_NOT_READY, /* (3) The physical drive cannot work */
|
||||||
|
FR_NO_FILE, /* (4) Could not find the file */
|
||||||
|
FR_NO_PATH, /* (5) Could not find the path */
|
||||||
|
FR_INVALID_NAME, /* (6) The path name format is invalid */
|
||||||
|
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
|
||||||
|
FR_EXIST, /* (8) Access denied due to prohibited access */
|
||||||
|
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
||||||
|
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
||||||
|
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
||||||
|
FR_NOT_ENABLED, /* (12) The volume has no work area */
|
||||||
|
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
|
||||||
|
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
|
||||||
|
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
||||||
|
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
|
||||||
|
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||||
|
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
|
||||||
|
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
||||||
|
} FRESULT;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
/* FatFs module application interface */
|
||||||
|
|
||||||
|
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
|
||||||
|
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||||
|
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
|
||||||
|
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
|
||||||
|
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
|
||||||
|
FRESULT f_truncate (FIL* fp); /* Truncate the file */
|
||||||
|
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
|
||||||
|
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
|
||||||
|
FRESULT f_closedir (DIR* dp); /* Close an open directory */
|
||||||
|
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
|
||||||
|
FRESULT f_seekdir(DIR *dj, int offset); /* Seek in directory */
|
||||||
|
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
|
||||||
|
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
|
||||||
|
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
|
||||||
|
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
|
||||||
|
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
||||||
|
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
||||||
|
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
|
||||||
|
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
|
||||||
|
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
||||||
|
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
||||||
|
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
|
||||||
|
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
|
||||||
|
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
||||||
|
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
||||||
|
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||||
|
FRESULT f_expand (FIL* fp, FSIZE_t fsz, BYTE opt); /* Allocate a contiguous block to the file */
|
||||||
|
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||||
|
FRESULT f_mkfs (const TCHAR* path, const MKFS_PARM* opt, void* work, UINT len); /* Create a FAT volume */
|
||||||
|
FRESULT f_fdisk (BYTE pdrv, const LBA_t ptbl[], void* work); /* Divide a physical drive into some partitions */
|
||||||
|
FRESULT f_setcp (WORD cp); /* Set current code page */
|
||||||
|
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
|
||||||
|
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
||||||
|
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
|
||||||
|
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
|
||||||
|
|
||||||
|
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
|
||||||
|
#define f_error(fp) ((fp)->err)
|
||||||
|
#define f_tell(fp) ((fp)->fptr)
|
||||||
|
#define f_size(fp) ((fp)->obj.objsize)
|
||||||
|
#define f_rewind(fp) f_lseek((fp), 0)
|
||||||
|
#define f_rewinddir(dp) f_readdir((dp), 0)
|
||||||
|
#define f_rmdir(path) f_unlink(path)
|
||||||
|
#define f_unmount(path) f_mount(0, path, 0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
/* Additional user defined functions */
|
||||||
|
|
||||||
|
/* RTC function */
|
||||||
|
#if !FF_FS_READONLY && !FF_FS_NORTC
|
||||||
|
DWORD get_fattime (void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* LFN support functions */
|
||||||
|
#if FF_USE_LFN >= 1 /* Code conversion (defined in unicode.c) */
|
||||||
|
WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */
|
||||||
|
WCHAR ff_uni2oem (DWORD uni, WORD cp); /* Unicode to OEM code conversion */
|
||||||
|
DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */
|
||||||
|
#endif
|
||||||
|
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
|
||||||
|
void* ff_memalloc (UINT msize); /* Allocate memory block */
|
||||||
|
void ff_memfree (void* mblock); /* Free memory block */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Sync functions */
|
||||||
|
#if FF_FS_REENTRANT
|
||||||
|
int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj); /* Create a sync object */
|
||||||
|
int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */
|
||||||
|
void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */
|
||||||
|
int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
/* Flags and offset address */
|
||||||
|
|
||||||
|
|
||||||
|
/* File access mode and open method flags (3rd argument of f_open) */
|
||||||
|
#define FA_READ 0x01
|
||||||
|
#define FA_WRITE 0x02
|
||||||
|
#define FA_OPEN_EXISTING 0x00
|
||||||
|
#define FA_CREATE_NEW 0x04
|
||||||
|
#define FA_CREATE_ALWAYS 0x08
|
||||||
|
#define FA_OPEN_ALWAYS 0x10
|
||||||
|
#define FA_OPEN_APPEND 0x30
|
||||||
|
|
||||||
|
/* Fast seek controls (2nd argument of f_lseek) */
|
||||||
|
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
|
||||||
|
|
||||||
|
/* Format options (2nd argument of f_mkfs) */
|
||||||
|
#define FM_FAT 0x01
|
||||||
|
#define FM_FAT32 0x02
|
||||||
|
#define FM_EXFAT 0x04
|
||||||
|
#define FM_ANY 0x07
|
||||||
|
#define FM_SFD 0x08
|
||||||
|
|
||||||
|
/* Filesystem type (FATFS.fs_type) */
|
||||||
|
#define FS_FAT12 1
|
||||||
|
#define FS_FAT16 2
|
||||||
|
#define FS_FAT32 3
|
||||||
|
#define FS_EXFAT 4
|
||||||
|
|
||||||
|
/* File attribute bits for directory entry (FILINFO.fattrib) */
|
||||||
|
#define AM_RDO 0x01 /* Read only */
|
||||||
|
#define AM_HID 0x02 /* Hidden */
|
||||||
|
#define AM_SYS 0x04 /* System */
|
||||||
|
#define AM_DIR 0x10 /* Directory */
|
||||||
|
#define AM_ARC 0x20 /* Archive */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* FF_DEFINED */
|
342
components/dfs/dfs_v1/filesystems/elmfat/ffconf.h
Normal file
342
components/dfs/dfs_v1/filesystems/elmfat/ffconf.h
Normal file
|
@ -0,0 +1,342 @@
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ FatFs Functional Configurations
|
||||||
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define FFCONF_DEF 86631 /* Revision ID */
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ Function Configurations
|
||||||
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define FF_FS_READONLY 0
|
||||||
|
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||||
|
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||||
|
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||||
|
/ and optional writing functions as well. */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_FS_MINIMIZE 0
|
||||||
|
/* This option defines minimization level to remove some basic API functions.
|
||||||
|
/
|
||||||
|
/ 0: Basic functions are fully enabled.
|
||||||
|
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
|
||||||
|
/ are removed.
|
||||||
|
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
|
||||||
|
/ 3: f_lseek() function is removed in addition to 2. */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_USE_FIND 0
|
||||||
|
/* This option switches filtered directory read functions, f_findfirst() and
|
||||||
|
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_USE_MKFS 1
|
||||||
|
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_USE_FASTSEEK 1
|
||||||
|
/* This option switches fast seek function. (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_USE_EXPAND 0
|
||||||
|
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_USE_CHMOD 0
|
||||||
|
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
|
||||||
|
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_USE_LABEL 0
|
||||||
|
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||||
|
/ (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_USE_FORWARD 0
|
||||||
|
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_USE_STRFUNC 0
|
||||||
|
#define FF_PRINT_LLI 0
|
||||||
|
#define FF_PRINT_FLOAT 0
|
||||||
|
#define FF_STRF_ENCODE 3
|
||||||
|
/* FF_USE_STRFUNC switches string functions, f_gets(), f_putc(), f_puts() and
|
||||||
|
/ f_printf().
|
||||||
|
/
|
||||||
|
/ 0: Disable. FF_PRINT_LLI, FF_PRINT_FLOAT and FF_STRF_ENCODE have no effect.
|
||||||
|
/ 1: Enable without LF-CRLF conversion.
|
||||||
|
/ 2: Enable with LF-CRLF conversion.
|
||||||
|
/
|
||||||
|
/ FF_PRINT_LLI = 1 makes f_printf() support long long argument and FF_PRINT_FLOAT = 1/2
|
||||||
|
makes f_printf() support floating point argument. These features want C99 or later.
|
||||||
|
/ When FF_LFN_UNICODE >= 1 with LFN enabled, string functions convert the character
|
||||||
|
/ encoding in it. FF_STRF_ENCODE selects assumption of character encoding ON THE FILE
|
||||||
|
/ to be read/written via those functions.
|
||||||
|
/
|
||||||
|
/ 0: ANSI/OEM in current CP
|
||||||
|
/ 1: Unicode in UTF-16LE
|
||||||
|
/ 2: Unicode in UTF-16BE
|
||||||
|
/ 3: Unicode in UTF-8
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ Locale and Namespace Configurations
|
||||||
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifdef RT_DFS_ELM_CODE_PAGE
|
||||||
|
# define FF_CODE_PAGE RT_DFS_ELM_CODE_PAGE
|
||||||
|
#else
|
||||||
|
# define FF_CODE_PAGE 936
|
||||||
|
#endif
|
||||||
|
/* This option specifies the OEM code page to be used on the target system.
|
||||||
|
/ Incorrect code page setting can cause a file open failure.
|
||||||
|
/
|
||||||
|
/ 437 - U.S.
|
||||||
|
/ 720 - Arabic
|
||||||
|
/ 737 - Greek
|
||||||
|
/ 771 - KBL
|
||||||
|
/ 775 - Baltic
|
||||||
|
/ 850 - Latin 1
|
||||||
|
/ 852 - Latin 2
|
||||||
|
/ 855 - Cyrillic
|
||||||
|
/ 857 - Turkish
|
||||||
|
/ 860 - Portuguese
|
||||||
|
/ 861 - Icelandic
|
||||||
|
/ 862 - Hebrew
|
||||||
|
/ 863 - Canadian French
|
||||||
|
/ 864 - Arabic
|
||||||
|
/ 865 - Nordic
|
||||||
|
/ 866 - Russian
|
||||||
|
/ 869 - Greek 2
|
||||||
|
/ 932 - Japanese (DBCS)
|
||||||
|
/ 936 - Simplified Chinese (DBCS)
|
||||||
|
/ 949 - Korean (DBCS)
|
||||||
|
/ 950 - Traditional Chinese (DBCS)
|
||||||
|
/ 0 - Include all code pages above and configured by f_setcp()
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#if RT_DFS_ELM_USE_LFN
|
||||||
|
#define FF_USE_LFN RT_DFS_ELM_USE_LFN
|
||||||
|
#define FF_MAX_LFN RT_DFS_ELM_MAX_LFN
|
||||||
|
#else
|
||||||
|
#define FF_USE_LFN 0 /* 0 to 3 */
|
||||||
|
#define FF_MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
|
||||||
|
#endif
|
||||||
|
/* The FF_USE_LFN switches the support for LFN (long file name).
|
||||||
|
/
|
||||||
|
/ 0: Disable LFN. FF_MAX_LFN has no effect.
|
||||||
|
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
|
||||||
|
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||||
|
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||||
|
/
|
||||||
|
/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
|
||||||
|
/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
|
||||||
|
/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
|
||||||
|
/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
|
||||||
|
/ be in range of 12 to 255. It is recommended to be set it 255 to fully support LFN
|
||||||
|
/ specification.
|
||||||
|
/ When use stack for the working buffer, take care on stack overflow. When use heap
|
||||||
|
/ memory for the working buffer, memory management functions, ff_memalloc() and
|
||||||
|
/ ff_memfree() exemplified in ffsystem.c, need to be added to the project. */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef RT_DFS_ELM_LFN_UNICODE
|
||||||
|
/* This option switches the character encoding on the API when LFN is enabled.
|
||||||
|
/
|
||||||
|
/ 0: ANSI/OEM in current CP (TCHAR = char)
|
||||||
|
/ 1: Unicode in UTF-16 (TCHAR = WCHAR)
|
||||||
|
/ 2: Unicode in UTF-8 (TCHAR = char)
|
||||||
|
/ 3: Unicode in UTF-32 (TCHAR = DWORD)
|
||||||
|
/
|
||||||
|
/ Also behavior of string I/O functions will be affected by this option.
|
||||||
|
/ When LFN is not enabled, this option has no effect. */
|
||||||
|
#define FF_LFN_UNICODE RT_DFS_ELM_LFN_UNICODE /* 0:ANSI/OEM or 1:Unicode */
|
||||||
|
#else
|
||||||
|
#define FF_LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
|
||||||
|
#endif
|
||||||
|
/* This option switches the character encoding on the API when LFN is enabled.
|
||||||
|
/
|
||||||
|
/ 0: ANSI/OEM in current CP (TCHAR = char)
|
||||||
|
/ 1: Unicode in UTF-16 (TCHAR = WCHAR)
|
||||||
|
/ 2: Unicode in UTF-8 (TCHAR = char)
|
||||||
|
/ 3: Unicode in UTF-32 (TCHAR = DWORD)
|
||||||
|
/
|
||||||
|
/ Also behavior of string I/O functions will be affected by this option.
|
||||||
|
/ When LFN is not enabled, this option has no effect. */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_LFN_BUF 255
|
||||||
|
#define FF_SFN_BUF 12
|
||||||
|
/* This set of options defines size of file name members in the FILINFO structure
|
||||||
|
/ which is used to read out directory items. These values should be suffcient for
|
||||||
|
/ the file names to read. The maximum possible length of the read file name depends
|
||||||
|
/ on character encoding. When LFN is not enabled, these options have no effect. */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_FS_RPATH 0
|
||||||
|
/* This option configures support for relative path.
|
||||||
|
/
|
||||||
|
/ 0: Disable relative path and remove related functions.
|
||||||
|
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
|
||||||
|
/ 2: f_getcwd() function is available in addition to 1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ Drive/Volume Configurations
|
||||||
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifdef RT_DFS_ELM_DRIVES
|
||||||
|
#define FF_VOLUMES RT_DFS_ELM_DRIVES
|
||||||
|
#else
|
||||||
|
#define FF_VOLUMES 1
|
||||||
|
#endif
|
||||||
|
/* Number of volumes (logical drives) to be used. (1-10) */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_STR_VOLUME_ID 0
|
||||||
|
#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
|
||||||
|
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
|
||||||
|
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
|
||||||
|
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
|
||||||
|
/ logical drives. Number of items must not be less than FF_VOLUMES. Valid
|
||||||
|
/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are
|
||||||
|
/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is
|
||||||
|
/ not defined, a user defined volume string table needs to be defined as:
|
||||||
|
/
|
||||||
|
/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",...
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_MULTI_PARTITION 0
|
||||||
|
/* This option switches support for multiple volumes on the physical drive.
|
||||||
|
/ By default (0), each logical drive number is bound to the same physical drive
|
||||||
|
/ number and only an FAT volume found on the physical drive will be mounted.
|
||||||
|
/ When this function is enabled (1), each logical drive number can be bound to
|
||||||
|
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
|
||||||
|
/ funciton will be available. */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_MIN_SS 512
|
||||||
|
#ifdef RT_DFS_ELM_MAX_SECTOR_SIZE
|
||||||
|
#define FF_MAX_SS RT_DFS_ELM_MAX_SECTOR_SIZE
|
||||||
|
#else
|
||||||
|
#define FF_MAX_SS 512 /* 512, 1024, 2048 or 4096 */
|
||||||
|
#endif
|
||||||
|
/* This set of options configures the range of sector size to be supported. (512,
|
||||||
|
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
|
||||||
|
/ harddisk, but a larger value may be required for on-board flash memory and some
|
||||||
|
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
|
||||||
|
/ for variable sector size mode and disk_ioctl() function needs to implement
|
||||||
|
/ GET_SECTOR_SIZE command. */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_LBA64 0
|
||||||
|
/* This option switches support for 64-bit LBA. (0:Disable or 1:Enable)
|
||||||
|
/ To enable the 64-bit LBA, also exFAT needs to be enabled. (FF_FS_EXFAT == 1) */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_MIN_GPT 0x10000000
|
||||||
|
/* Minimum number of sectors to switch GPT as partitioning format in f_mkfs and
|
||||||
|
/ f_fdisk function. 0x100000000 max. This option has no effect when FF_LBA64 == 0. */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_USE_TRIM 0
|
||||||
|
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
|
||||||
|
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
|
||||||
|
/ disk_ioctl() function. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ System Configurations
|
||||||
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define FF_FS_TINY 0
|
||||||
|
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||||
|
/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
|
||||||
|
/ Instead of private sector buffer eliminated from the file object, common sector
|
||||||
|
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
|
||||||
|
|
||||||
|
#ifdef RT_DFS_ELM_USE_EXFAT
|
||||||
|
#define FF_FS_EXFAT 1
|
||||||
|
#else
|
||||||
|
#define FF_FS_EXFAT 0
|
||||||
|
#endif
|
||||||
|
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
|
||||||
|
/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)
|
||||||
|
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_FS_NORTC 0
|
||||||
|
#define FF_NORTC_MON 1
|
||||||
|
#define FF_NORTC_MDAY 1
|
||||||
|
#define FF_NORTC_YEAR 2020
|
||||||
|
/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have
|
||||||
|
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
|
||||||
|
/ the timestamp function. Every object modified by FatFs will have a fixed timestamp
|
||||||
|
/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
|
||||||
|
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
|
||||||
|
/ added to the project to read current time form real-time clock. FF_NORTC_MON,
|
||||||
|
/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
|
||||||
|
/ These options have no effect in read-only configuration (FF_FS_READONLY = 1). */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_FS_NOFSINFO 0
|
||||||
|
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
||||||
|
/ option, and f_getfree() function at first time after volume mount will force
|
||||||
|
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
||||||
|
/
|
||||||
|
/ bit0=0: Use free cluster count in the FSINFO if available.
|
||||||
|
/ bit0=1: Do not trust free cluster count in the FSINFO.
|
||||||
|
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
|
||||||
|
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_FS_LOCK 0
|
||||||
|
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
|
||||||
|
/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
|
||||||
|
/ is 1.
|
||||||
|
/
|
||||||
|
/ 0: Disable file lock function. To avoid volume corruption, application program
|
||||||
|
/ should avoid illegal open, remove and rename to the open objects.
|
||||||
|
/ >0: Enable file lock function. The value defines how many files/sub-directories
|
||||||
|
/ can be opened simultaneously under file lock control. Note that the file
|
||||||
|
/ lock control is independent of re-entrancy. */
|
||||||
|
|
||||||
|
|
||||||
|
/* #include <somertos.h> // O/S definitions */
|
||||||
|
#include <rtdef.h>
|
||||||
|
#ifdef RT_DFS_ELM_REENTRANT
|
||||||
|
#define FF_FS_REENTRANT 1 /* 0 or 1 */
|
||||||
|
#else
|
||||||
|
#define FF_FS_REENTRANT 0 /* 0:Disable or 1:Enable */
|
||||||
|
#endif
|
||||||
|
#ifndef RT_DFS_ELM_MUTEX_TIMEOUT
|
||||||
|
#define RT_DFS_ELM_MUTEX_TIMEOUT 3000
|
||||||
|
#endif
|
||||||
|
#define FF_FS_TIMEOUT RT_DFS_ELM_MUTEX_TIMEOUT
|
||||||
|
#define FF_SYNC_t rt_mutex_t
|
||||||
|
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
|
||||||
|
/ module itself. Note that regardless of this option, file access to different
|
||||||
|
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
|
||||||
|
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
|
||||||
|
/ to the same volume is under control of this function.
|
||||||
|
/
|
||||||
|
/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
|
||||||
|
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
|
||||||
|
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
|
||||||
|
/ function, must be added to the project. Samples are available in
|
||||||
|
/ option/syscall.c.
|
||||||
|
/
|
||||||
|
/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
|
||||||
|
/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
||||||
|
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
|
||||||
|
/ included somewhere in the scope of ff.h. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--- End of configuration options ---*/
|
15593
components/dfs/dfs_v1/filesystems/elmfat/ffunicode.c
Normal file
15593
components/dfs/dfs_v1/filesystems/elmfat/ffunicode.c
Normal file
File diff suppressed because it is too large
Load diff
13
components/dfs/dfs_v1/filesystems/nfs/SConscript
Normal file
13
components/dfs/dfs_v1/filesystems/nfs/SConscript
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# RT-Thread building script for component
|
||||||
|
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
src = Glob('*.c') + Glob('rpc/*.c')
|
||||||
|
CPPPATH = [cwd]
|
||||||
|
|
||||||
|
SrcRemove(src, ['rpc/auth_none.c'])
|
||||||
|
|
||||||
|
group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS', 'RT_USING_DFS_NFS'], CPPPATH = CPPPATH)
|
||||||
|
|
||||||
|
Return('group')
|
1192
components/dfs/dfs_v1/filesystems/nfs/dfs_nfs.c
Normal file
1192
components/dfs/dfs_v1/filesystems/nfs/dfs_nfs.c
Normal file
File diff suppressed because it is too large
Load diff
15
components/dfs/dfs_v1/filesystems/nfs/dfs_nfs.h
Normal file
15
components/dfs/dfs_v1/filesystems/nfs/dfs_nfs.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __NFS_H__
|
||||||
|
#define __NFS_H__
|
||||||
|
|
||||||
|
int nfs_init(void);
|
||||||
|
|
||||||
|
#endif
|
131
components/dfs/dfs_v1/filesystems/nfs/mount.h
Normal file
131
components/dfs/dfs_v1/filesystems/nfs/mount.h
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Please do not edit this file.
|
||||||
|
* It was generated using rpcgen.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MOUNT_H_RPCGEN
|
||||||
|
#define _MOUNT_H_RPCGEN
|
||||||
|
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This file is copied from RFC1813
|
||||||
|
* Copyright 1995 Sun Micrososystems (I assume)
|
||||||
|
*/
|
||||||
|
#define MNTPATHLEN 1024
|
||||||
|
#define MNTNAMLEN 255
|
||||||
|
#define FHSIZE3 64
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int fhandle3_len;
|
||||||
|
char *fhandle3_val;
|
||||||
|
} fhandle3;
|
||||||
|
|
||||||
|
typedef char *dirpath;
|
||||||
|
|
||||||
|
typedef char *name;
|
||||||
|
|
||||||
|
typedef struct exportnode *exports;
|
||||||
|
|
||||||
|
typedef struct groupnode *groups;
|
||||||
|
|
||||||
|
typedef struct mountbody *mountlist;
|
||||||
|
|
||||||
|
enum mountstat3 {
|
||||||
|
MNT3_OK = 0,
|
||||||
|
MNT3ERR_PERM = 1,
|
||||||
|
MNT3ERR_NOENT = 2,
|
||||||
|
MNT3ERR_IO = 5,
|
||||||
|
MNT3ERR_ACCES = 13,
|
||||||
|
MNT3ERR_NOTDIR = 20,
|
||||||
|
MNT3ERR_INVAL = 22,
|
||||||
|
MNT3ERR_NAMETOOLONG = 63,
|
||||||
|
MNT3ERR_NOTSUPP = 10004,
|
||||||
|
MNT3ERR_SERVERFAULT = 10006
|
||||||
|
};
|
||||||
|
typedef enum mountstat3 mountstat3;
|
||||||
|
|
||||||
|
struct mountres3_ok {
|
||||||
|
fhandle3 fhandle;
|
||||||
|
struct {
|
||||||
|
unsigned int auth_flavors_len;
|
||||||
|
int *auth_flavors_val;
|
||||||
|
} auth_flavors;
|
||||||
|
};
|
||||||
|
typedef struct mountres3_ok mountres3_ok;
|
||||||
|
|
||||||
|
struct mountres3 {
|
||||||
|
mountstat3 fhs_status;
|
||||||
|
union {
|
||||||
|
mountres3_ok mountinfo;
|
||||||
|
} mountres3_u;
|
||||||
|
};
|
||||||
|
typedef struct mountres3 mountres3;
|
||||||
|
|
||||||
|
struct mountbody {
|
||||||
|
name ml_hostname;
|
||||||
|
dirpath ml_directory;
|
||||||
|
mountlist ml_next;
|
||||||
|
};
|
||||||
|
typedef struct mountbody mountbody;
|
||||||
|
|
||||||
|
struct groupnode {
|
||||||
|
name gr_name;
|
||||||
|
groups gr_next;
|
||||||
|
};
|
||||||
|
typedef struct groupnode groupnode;
|
||||||
|
|
||||||
|
struct exportnode {
|
||||||
|
dirpath ex_dir;
|
||||||
|
groups ex_groups;
|
||||||
|
exports ex_next;
|
||||||
|
};
|
||||||
|
typedef struct exportnode exportnode;
|
||||||
|
|
||||||
|
#define MOUNT_PROGRAM 100005
|
||||||
|
#define MOUNT_V3 3
|
||||||
|
|
||||||
|
#define MOUNTPROC3_NULL 0
|
||||||
|
extern enum clnt_stat mountproc3_null_3(void *, CLIENT *);
|
||||||
|
#define MOUNTPROC3_MNT 1
|
||||||
|
extern enum clnt_stat mountproc3_mnt_3(dirpath , mountres3 *, CLIENT *);
|
||||||
|
#define MOUNTPROC3_DUMP 2
|
||||||
|
extern enum clnt_stat mountproc3_dump_3(mountlist *, CLIENT *);
|
||||||
|
#define MOUNTPROC3_UMNT 3
|
||||||
|
extern enum clnt_stat mountproc3_umnt_3(dirpath , void *, CLIENT *);
|
||||||
|
#define MOUNTPROC3_UMNTALL 4
|
||||||
|
extern enum clnt_stat mountproc3_umntall_3(void *, CLIENT *);
|
||||||
|
#define MOUNTPROC3_EXPORT 5
|
||||||
|
extern enum clnt_stat mountproc3_export_3(exports *, CLIENT *);
|
||||||
|
|
||||||
|
/* the xdr functions */
|
||||||
|
|
||||||
|
extern bool_t xdr_fhandle3(XDR *, fhandle3*);
|
||||||
|
extern bool_t xdr_dirpath(XDR *, dirpath*);
|
||||||
|
extern bool_t xdr_name(XDR *, name*);
|
||||||
|
extern bool_t xdr_exports(XDR *, exports*);
|
||||||
|
extern bool_t xdr_groups(XDR *, groups*);
|
||||||
|
extern bool_t xdr_mountlist(XDR *, mountlist*);
|
||||||
|
extern bool_t xdr_mountstat3(XDR *, mountstat3*);
|
||||||
|
extern bool_t xdr_mountres3_ok(XDR *, mountres3_ok*);
|
||||||
|
extern bool_t xdr_mountres3(XDR *, mountres3*);
|
||||||
|
extern bool_t xdr_mountbody(XDR *, mountbody*);
|
||||||
|
extern bool_t xdr_groupnode(XDR *, groupnode*);
|
||||||
|
extern bool_t xdr_exportnode(XDR *, exportnode*);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !_MOUNT_H_RPCGEN */
|
68
components/dfs/dfs_v1/filesystems/nfs/mount.x
Normal file
68
components/dfs/dfs_v1/filesystems/nfs/mount.x
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
%/* This file is copied from RFC1813
|
||||||
|
% * Copyright 1995 Sun Micrososystems (I assume)
|
||||||
|
% */
|
||||||
|
|
||||||
|
const MNTPATHLEN = 1024; /* Maximum bytes in a path name */
|
||||||
|
const MNTNAMLEN = 255; /* Maximum bytes in a name */
|
||||||
|
const FHSIZE3 = 64; /* Maximum bytes in a V3 file handle */
|
||||||
|
|
||||||
|
typedef opaque fhandle3<FHSIZE3>;
|
||||||
|
typedef string dirpath<MNTPATHLEN>;
|
||||||
|
typedef string name<MNTNAMLEN>;
|
||||||
|
|
||||||
|
typedef struct exportnode *exports;
|
||||||
|
typedef struct groupnode *groups;
|
||||||
|
typedef struct mountbody *mountlist;
|
||||||
|
|
||||||
|
enum mountstat3 {
|
||||||
|
MNT3_OK = 0, /* no error */
|
||||||
|
MNT3ERR_PERM = 1, /* Not owner */
|
||||||
|
MNT3ERR_NOENT = 2, /* No such file or directory */
|
||||||
|
MNT3ERR_IO = 5, /* I/O error */
|
||||||
|
MNT3ERR_ACCES = 13, /* Permission denied */
|
||||||
|
MNT3ERR_NOTDIR = 20, /* Not a directory */
|
||||||
|
MNT3ERR_INVAL = 22, /* Invalid argument */
|
||||||
|
MNT3ERR_NAMETOOLONG = 63, /* Filename too long */
|
||||||
|
MNT3ERR_NOTSUPP = 10004, /* Operation not supported */
|
||||||
|
MNT3ERR_SERVERFAULT = 10006 /* A failure on the server */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mountres3_ok {
|
||||||
|
fhandle3 fhandle;
|
||||||
|
int auth_flavors<>;
|
||||||
|
};
|
||||||
|
|
||||||
|
union mountres3 switch (mountstat3 fhs_status) {
|
||||||
|
case MNT3_OK:
|
||||||
|
mountres3_ok mountinfo;
|
||||||
|
default:
|
||||||
|
void;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mountbody {
|
||||||
|
name ml_hostname;
|
||||||
|
dirpath ml_directory;
|
||||||
|
mountlist ml_next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct groupnode {
|
||||||
|
name gr_name;
|
||||||
|
groups gr_next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct exportnode {
|
||||||
|
dirpath ex_dir;
|
||||||
|
groups ex_groups;
|
||||||
|
exports ex_next;
|
||||||
|
};
|
||||||
|
|
||||||
|
program MOUNT_PROGRAM {
|
||||||
|
version MOUNT_V3 {
|
||||||
|
void MOUNTPROC3_NULL(void) = 0;
|
||||||
|
mountres3 MOUNTPROC3_MNT(dirpath) = 1;
|
||||||
|
mountlist MOUNTPROC3_DUMP(void) = 2;
|
||||||
|
void MOUNTPROC3_UMNT(dirpath) = 3;
|
||||||
|
void MOUNTPROC3_UMNTALL(void) = 4;
|
||||||
|
exports MOUNTPROC3_EXPORT(void) = 5;
|
||||||
|
} = 3;
|
||||||
|
} = 100005;
|
78
components/dfs/dfs_v1/filesystems/nfs/mount_clnt.c
Normal file
78
components/dfs/dfs_v1/filesystems/nfs/mount_clnt.c
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Please do not edit this file.
|
||||||
|
* It was generated using rpcgen.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h> /* for memset */
|
||||||
|
#include "mount.h"
|
||||||
|
|
||||||
|
/* This file is copied from RFC1813
|
||||||
|
* Copyright 1995 Sun Micrososystems (I assume)
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef char* caddr_t;
|
||||||
|
|
||||||
|
/* Default timeout can be changed using clnt_control() */
|
||||||
|
static struct timeval TIMEOUT = { 25, 0 };
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
mountproc3_null_3(void *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, MOUNTPROC3_NULL,
|
||||||
|
(xdrproc_t) xdr_void, (caddr_t) NULL,
|
||||||
|
(xdrproc_t) xdr_void, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
mountproc3_mnt_3(dirpath arg1, mountres3 *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, MOUNTPROC3_MNT,
|
||||||
|
(xdrproc_t) xdr_dirpath, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_mountres3, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
mountproc3_dump_3(mountlist *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, MOUNTPROC3_DUMP,
|
||||||
|
(xdrproc_t) xdr_void, (caddr_t) NULL,
|
||||||
|
(xdrproc_t) xdr_mountlist, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
mountproc3_umnt_3(dirpath arg1, void *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, MOUNTPROC3_UMNT,
|
||||||
|
(xdrproc_t) xdr_dirpath, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_void, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
mountproc3_umntall_3(void *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, MOUNTPROC3_UMNTALL,
|
||||||
|
(xdrproc_t) xdr_void, (caddr_t) NULL,
|
||||||
|
(xdrproc_t) xdr_void, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
mountproc3_export_3(exports *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, MOUNTPROC3_EXPORT,
|
||||||
|
(xdrproc_t) xdr_void, (caddr_t) NULL,
|
||||||
|
(xdrproc_t) xdr_exports, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
142
components/dfs/dfs_v1/filesystems/nfs/mount_xdr.c
Normal file
142
components/dfs/dfs_v1/filesystems/nfs/mount_xdr.c
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Please do not edit this file.
|
||||||
|
* It was generated using rpcgen.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mount.h"
|
||||||
|
/* This file is copied from RFC1813
|
||||||
|
* Copyright 1995 Sun Micrososystems (I assume)
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_fhandle3(register XDR *xdrs, fhandle3 *objp)
|
||||||
|
{
|
||||||
|
if (!xdr_bytes(xdrs, (char **)&objp->fhandle3_val, (unsigned int *) &objp->fhandle3_len, FHSIZE3))
|
||||||
|
return (FALSE);
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_dirpath(register XDR *xdrs, dirpath *objp)
|
||||||
|
{
|
||||||
|
if (!xdr_string(xdrs, objp, MNTPATHLEN))
|
||||||
|
return (FALSE);
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_name(register XDR *xdrs, name *objp)
|
||||||
|
{
|
||||||
|
if (!xdr_string(xdrs, objp, MNTNAMLEN))
|
||||||
|
return (FALSE);
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_exports(register XDR *xdrs, exports *objp)
|
||||||
|
{
|
||||||
|
if (!xdr_pointer(xdrs, (char **)objp, sizeof (struct exportnode), (xdrproc_t) xdr_exportnode))
|
||||||
|
return (FALSE);
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_groups(register XDR *xdrs, groups *objp)
|
||||||
|
{
|
||||||
|
if (!xdr_pointer(xdrs, (char **)objp, sizeof (struct groupnode), (xdrproc_t) xdr_groupnode))
|
||||||
|
return (FALSE);
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_mountlist(register XDR *xdrs, mountlist *objp)
|
||||||
|
{
|
||||||
|
if (!xdr_pointer(xdrs, (char **)objp, sizeof (struct mountbody), (xdrproc_t) xdr_mountbody))
|
||||||
|
return (FALSE);
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_mountstat3(register XDR *xdrs, mountstat3 *objp)
|
||||||
|
{
|
||||||
|
int enum_objp;
|
||||||
|
|
||||||
|
enum_objp = *objp;
|
||||||
|
|
||||||
|
if (!xdr_enum(xdrs, (enum_t *)&enum_objp))
|
||||||
|
{
|
||||||
|
*objp = (mountstat3)enum_objp;
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_mountres3_ok(register XDR *xdrs, mountres3_ok *objp)
|
||||||
|
{
|
||||||
|
if (!xdr_fhandle3(xdrs, &objp->fhandle))
|
||||||
|
return (FALSE);
|
||||||
|
if (!xdr_array(xdrs, (char **)&objp->auth_flavors.auth_flavors_val, (unsigned int *) &objp->auth_flavors.auth_flavors_len, ~0,
|
||||||
|
sizeof (int), (xdrproc_t) xdr_int))
|
||||||
|
return (FALSE);
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_mountres3(register XDR *xdrs, mountres3 *objp)
|
||||||
|
{
|
||||||
|
if (!xdr_mountstat3(xdrs, &objp->fhs_status))
|
||||||
|
return (FALSE);
|
||||||
|
switch (objp->fhs_status) {
|
||||||
|
case MNT3_OK:
|
||||||
|
if (!xdr_mountres3_ok(xdrs, &objp->mountres3_u.mountinfo))
|
||||||
|
return (FALSE);
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_mountbody(register XDR *xdrs, mountbody *objp)
|
||||||
|
{
|
||||||
|
if (!xdr_name(xdrs, &objp->ml_hostname))
|
||||||
|
return (FALSE);
|
||||||
|
if (!xdr_dirpath(xdrs, &objp->ml_directory))
|
||||||
|
return (FALSE);
|
||||||
|
if (!xdr_mountlist(xdrs, &objp->ml_next))
|
||||||
|
return (FALSE);
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_groupnode(register XDR *xdrs, groupnode *objp)
|
||||||
|
{
|
||||||
|
if (!xdr_name(xdrs, &objp->gr_name))
|
||||||
|
return (FALSE);
|
||||||
|
if (!xdr_groups(xdrs, &objp->gr_next))
|
||||||
|
return (FALSE);
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_exportnode(register XDR *xdrs, exportnode *objp)
|
||||||
|
{
|
||||||
|
if (!xdr_dirpath(xdrs, &objp->ex_dir))
|
||||||
|
return (FALSE);
|
||||||
|
if (!xdr_groups(xdrs, &objp->ex_groups))
|
||||||
|
return (FALSE);
|
||||||
|
if (!xdr_exports(xdrs, &objp->ex_next))
|
||||||
|
return (FALSE);
|
||||||
|
return (TRUE);
|
||||||
|
}
|
1110
components/dfs/dfs_v1/filesystems/nfs/nfs.h
Normal file
1110
components/dfs/dfs_v1/filesystems/nfs/nfs.h
Normal file
File diff suppressed because it is too large
Load diff
774
components/dfs/dfs_v1/filesystems/nfs/nfs.x
Normal file
774
components/dfs/dfs_v1/filesystems/nfs/nfs.x
Normal file
|
@ -0,0 +1,774 @@
|
||||||
|
%/* This file is copied from RFC1813
|
||||||
|
% * Copyright 1995 Sun Micrososystems (I assume)
|
||||||
|
% */
|
||||||
|
|
||||||
|
const NFS3_FHSIZE = 64;
|
||||||
|
const NFS3_COOKIEVERFSIZE = 8;
|
||||||
|
const NFS3_CREATEVERFSIZE = 8;
|
||||||
|
const NFS3_WRITEVERFSIZE = 8;
|
||||||
|
|
||||||
|
const ACCESS3_READ = 0x0001;
|
||||||
|
const ACCESS3_LOOKUP = 0x0002;
|
||||||
|
const ACCESS3_MODIFY = 0x0004;
|
||||||
|
const ACCESS3_EXTEND = 0x0008;
|
||||||
|
const ACCESS3_DELETE = 0x0010;
|
||||||
|
const ACCESS3_EXECUTE = 0x0020;
|
||||||
|
|
||||||
|
const FSF3_LINK = 0x0001;
|
||||||
|
const FSF3_SYMLINK = 0x0002;
|
||||||
|
const FSF3_HOMOGENEOUS = 0x0008;
|
||||||
|
const FSF3_CANSETTIME = 0x0010;
|
||||||
|
|
||||||
|
typedef unsigned hyper uint64;
|
||||||
|
typedef hyper int64;
|
||||||
|
typedef unsigned long uint32;
|
||||||
|
typedef long int32;
|
||||||
|
typedef string filename3<>;
|
||||||
|
typedef string nfspath3<>;
|
||||||
|
typedef uint64 fileid3;
|
||||||
|
typedef uint64 cookie3;
|
||||||
|
typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
|
||||||
|
typedef opaque createverf3[NFS3_CREATEVERFSIZE];
|
||||||
|
typedef opaque writeverf3[NFS3_WRITEVERFSIZE];
|
||||||
|
typedef uint32 uid3;
|
||||||
|
typedef uint32 gid3;
|
||||||
|
typedef uint64 size3;
|
||||||
|
typedef uint64 offset3;
|
||||||
|
typedef uint32 mode3;
|
||||||
|
typedef uint32 count3;
|
||||||
|
|
||||||
|
enum nfsstat3 {
|
||||||
|
NFS3_OK = 0,
|
||||||
|
NFS3ERR_PERM = 1,
|
||||||
|
NFS3ERR_NOENT = 2,
|
||||||
|
NFS3ERR_IO = 5,
|
||||||
|
NFS3ERR_NXIO = 6,
|
||||||
|
NFS3ERR_ACCES = 13,
|
||||||
|
NFS3ERR_EXIST = 17,
|
||||||
|
NFS3ERR_XDEV = 18,
|
||||||
|
NFS3ERR_NODEV = 19,
|
||||||
|
NFS3ERR_NOTDIR = 20,
|
||||||
|
NFS3ERR_ISDIR = 21,
|
||||||
|
NFS3ERR_INVAL = 22,
|
||||||
|
NFS3ERR_FBIG = 27,
|
||||||
|
NFS3ERR_NOSPC = 28,
|
||||||
|
NFS3ERR_ROFS = 30,
|
||||||
|
NFS3ERR_MLINK = 31,
|
||||||
|
NFS3ERR_NAMETOOLONG = 63,
|
||||||
|
NFS3ERR_NOTEMPTY = 66,
|
||||||
|
NFS3ERR_DQUOT = 69,
|
||||||
|
NFS3ERR_STALE = 70,
|
||||||
|
NFS3ERR_REMOTE = 71,
|
||||||
|
NFS3ERR_BADHANDLE = 10001,
|
||||||
|
NFS3ERR_NOT_SYNC = 10002,
|
||||||
|
NFS3ERR_BAD_COOKIE = 10003,
|
||||||
|
NFS3ERR_NOTSUPP = 10004,
|
||||||
|
NFS3ERR_TOOSMALL = 10005,
|
||||||
|
NFS3ERR_SERVERFAULT = 10006,
|
||||||
|
NFS3ERR_BADTYPE = 10007,
|
||||||
|
NFS3ERR_JUKEBOX = 10008
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ftype3 {
|
||||||
|
NFS3REG = 1,
|
||||||
|
NFS3DIR = 2,
|
||||||
|
NFS3BLK = 3,
|
||||||
|
NFS3CHR = 4,
|
||||||
|
NFS3LNK = 5,
|
||||||
|
NFS3SOCK = 6,
|
||||||
|
NFS3FIFO = 7
|
||||||
|
};
|
||||||
|
enum stable_how {
|
||||||
|
UNSTABLE = 0,
|
||||||
|
DATA_SYNC = 1,
|
||||||
|
FILE_SYNC = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
enum createmode3 {
|
||||||
|
UNCHECKED = 0,
|
||||||
|
GUARDED = 1,
|
||||||
|
EXCLUSIVE = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
struct specdata3 {
|
||||||
|
uint32 specdata1;
|
||||||
|
uint32 specdata2;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nfs_fh3 {
|
||||||
|
opaque data<NFS3_FHSIZE>;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nfstime3 {
|
||||||
|
uint32 seconds;
|
||||||
|
uint32 nseconds;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fattr3 {
|
||||||
|
ftype3 type;
|
||||||
|
mode3 mode;
|
||||||
|
uint32 nlink;
|
||||||
|
uid3 uid;
|
||||||
|
gid3 gid;
|
||||||
|
size3 size;
|
||||||
|
size3 used;
|
||||||
|
specdata3 rdev;
|
||||||
|
uint64 fsid;
|
||||||
|
fileid3 fileid;
|
||||||
|
nfstime3 atime;
|
||||||
|
nfstime3 mtime;
|
||||||
|
nfstime3 ctime;
|
||||||
|
};
|
||||||
|
|
||||||
|
union post_op_attr switch (bool attributes_follow) {
|
||||||
|
case TRUE:
|
||||||
|
fattr3 attributes;
|
||||||
|
case FALSE:
|
||||||
|
void;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wcc_attr {
|
||||||
|
size3 size;
|
||||||
|
nfstime3 mtime;
|
||||||
|
nfstime3 ctime;
|
||||||
|
};
|
||||||
|
|
||||||
|
union pre_op_attr switch (bool attributes_follow) {
|
||||||
|
case TRUE:
|
||||||
|
wcc_attr attributes;
|
||||||
|
case FALSE:
|
||||||
|
void;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wcc_data {
|
||||||
|
pre_op_attr before;
|
||||||
|
post_op_attr after;
|
||||||
|
};
|
||||||
|
|
||||||
|
union post_op_fh3 switch (bool handle_follows) {
|
||||||
|
case TRUE:
|
||||||
|
nfs_fh3 handle;
|
||||||
|
case FALSE:
|
||||||
|
void;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum time_how {
|
||||||
|
DONT_CHANGE = 0,
|
||||||
|
SET_TO_SERVER_TIME = 1,
|
||||||
|
SET_TO_CLIENT_TIME = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
union set_mode3 switch (bool set_it) {
|
||||||
|
case TRUE:
|
||||||
|
mode3 mode;
|
||||||
|
default:
|
||||||
|
void;
|
||||||
|
};
|
||||||
|
|
||||||
|
union set_uid3 switch (bool set_it) {
|
||||||
|
case TRUE:
|
||||||
|
uid3 uid;
|
||||||
|
default:
|
||||||
|
void;
|
||||||
|
};
|
||||||
|
|
||||||
|
union set_gid3 switch (bool set_it) {
|
||||||
|
case TRUE:
|
||||||
|
gid3 gid;
|
||||||
|
default:
|
||||||
|
void;
|
||||||
|
};
|
||||||
|
|
||||||
|
union set_size3 switch (bool set_it) {
|
||||||
|
case TRUE:
|
||||||
|
size3 size;
|
||||||
|
default:
|
||||||
|
void;
|
||||||
|
};
|
||||||
|
|
||||||
|
union set_atime switch (time_how set_it) {
|
||||||
|
case SET_TO_CLIENT_TIME:
|
||||||
|
nfstime3 atime;
|
||||||
|
default:
|
||||||
|
void;
|
||||||
|
};
|
||||||
|
|
||||||
|
union set_mtime switch (time_how set_it) {
|
||||||
|
case SET_TO_CLIENT_TIME:
|
||||||
|
nfstime3 mtime;
|
||||||
|
default:
|
||||||
|
void;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sattr3 {
|
||||||
|
set_mode3 mode;
|
||||||
|
set_uid3 uid;
|
||||||
|
set_gid3 gid;
|
||||||
|
set_size3 size;
|
||||||
|
set_atime atime;
|
||||||
|
set_mtime mtime;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct diropargs3 {
|
||||||
|
nfs_fh3 dir;
|
||||||
|
filename3 name;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct GETATTR3args {
|
||||||
|
nfs_fh3 object;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GETATTR3resok {
|
||||||
|
fattr3 obj_attributes;
|
||||||
|
};
|
||||||
|
|
||||||
|
union GETATTR3res switch (nfsstat3 status) {
|
||||||
|
case NFS3_OK:
|
||||||
|
GETATTR3resok resok;
|
||||||
|
default:
|
||||||
|
void;
|
||||||
|
};
|
||||||
|
|
||||||
|
union sattrguard3 switch (bool check) {
|
||||||
|
case TRUE:
|
||||||
|
nfstime3 obj_ctime;
|
||||||
|
case FALSE:
|
||||||
|
void;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SETATTR3args {
|
||||||
|
nfs_fh3 object;
|
||||||
|
sattr3 new_attributes;
|
||||||
|
sattrguard3 guard;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SETATTR3resok {
|
||||||
|
wcc_data obj_wcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SETATTR3resfail {
|
||||||
|
wcc_data obj_wcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
union SETATTR3res switch (nfsstat3 status) {
|
||||||
|
case NFS3_OK:
|
||||||
|
SETATTR3resok resok;
|
||||||
|
default:
|
||||||
|
SETATTR3resfail resfail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LOOKUP3args {
|
||||||
|
diropargs3 what;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LOOKUP3resok {
|
||||||
|
nfs_fh3 object;
|
||||||
|
post_op_attr obj_attributes;
|
||||||
|
post_op_attr dir_attributes;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LOOKUP3resfail {
|
||||||
|
post_op_attr dir_attributes;
|
||||||
|
};
|
||||||
|
|
||||||
|
union LOOKUP3res switch (nfsstat3 status) {
|
||||||
|
case NFS3_OK:
|
||||||
|
LOOKUP3resok resok;
|
||||||
|
default:
|
||||||
|
LOOKUP3resfail resfail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ACCESS3args {
|
||||||
|
nfs_fh3 object;
|
||||||
|
uint32 access;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ACCESS3resok {
|
||||||
|
post_op_attr obj_attributes;
|
||||||
|
uint32 access;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ACCESS3resfail {
|
||||||
|
post_op_attr obj_attributes;
|
||||||
|
};
|
||||||
|
|
||||||
|
union ACCESS3res switch (nfsstat3 status) {
|
||||||
|
case NFS3_OK:
|
||||||
|
ACCESS3resok resok;
|
||||||
|
default:
|
||||||
|
ACCESS3resfail resfail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct READLINK3args {
|
||||||
|
nfs_fh3 symlink;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct READLINK3resok {
|
||||||
|
post_op_attr symlink_attributes;
|
||||||
|
nfspath3 data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct READLINK3resfail {
|
||||||
|
post_op_attr symlink_attributes;
|
||||||
|
};
|
||||||
|
|
||||||
|
union READLINK3res switch (nfsstat3 status) {
|
||||||
|
case NFS3_OK:
|
||||||
|
READLINK3resok resok;
|
||||||
|
default:
|
||||||
|
READLINK3resfail resfail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct READ3args {
|
||||||
|
nfs_fh3 file;
|
||||||
|
offset3 offset;
|
||||||
|
count3 count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct READ3resok {
|
||||||
|
post_op_attr file_attributes;
|
||||||
|
count3 count;
|
||||||
|
bool eof;
|
||||||
|
opaque data<>;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct READ3resfail {
|
||||||
|
post_op_attr file_attributes;
|
||||||
|
};
|
||||||
|
|
||||||
|
union READ3res switch (nfsstat3 status) {
|
||||||
|
case NFS3_OK:
|
||||||
|
READ3resok resok;
|
||||||
|
default:
|
||||||
|
READ3resfail resfail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WRITE3args {
|
||||||
|
nfs_fh3 file;
|
||||||
|
offset3 offset;
|
||||||
|
count3 count;
|
||||||
|
stable_how stable;
|
||||||
|
opaque data<>;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WRITE3resok {
|
||||||
|
wcc_data file_wcc;
|
||||||
|
count3 count;
|
||||||
|
stable_how committed;
|
||||||
|
writeverf3 verf;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WRITE3resfail {
|
||||||
|
wcc_data file_wcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
union WRITE3res switch (nfsstat3 status) {
|
||||||
|
case NFS3_OK:
|
||||||
|
WRITE3resok resok;
|
||||||
|
default:
|
||||||
|
WRITE3resfail resfail;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
union createhow3 switch (createmode3 mode) {
|
||||||
|
case UNCHECKED:
|
||||||
|
case GUARDED:
|
||||||
|
sattr3 obj_attributes;
|
||||||
|
case EXCLUSIVE:
|
||||||
|
createverf3 verf;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CREATE3args {
|
||||||
|
diropargs3 where;
|
||||||
|
createhow3 how;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CREATE3resok {
|
||||||
|
post_op_fh3 obj;
|
||||||
|
post_op_attr obj_attributes;
|
||||||
|
wcc_data dir_wcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CREATE3resfail {
|
||||||
|
wcc_data dir_wcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
union CREATE3res switch (nfsstat3 status) {
|
||||||
|
case NFS3_OK:
|
||||||
|
CREATE3resok resok;
|
||||||
|
default:
|
||||||
|
CREATE3resfail resfail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MKDIR3args {
|
||||||
|
diropargs3 where;
|
||||||
|
sattr3 attributes;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MKDIR3resok {
|
||||||
|
post_op_fh3 obj;
|
||||||
|
post_op_attr obj_attributes;
|
||||||
|
wcc_data dir_wcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MKDIR3resfail {
|
||||||
|
wcc_data dir_wcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
union MKDIR3res switch (nfsstat3 status) {
|
||||||
|
case NFS3_OK:
|
||||||
|
MKDIR3resok resok;
|
||||||
|
default:
|
||||||
|
MKDIR3resfail resfail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct symlinkdata3 {
|
||||||
|
sattr3 symlink_attributes;
|
||||||
|
nfspath3 symlink_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SYMLINK3args {
|
||||||
|
diropargs3 where;
|
||||||
|
symlinkdata3 symlink;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SYMLINK3resok {
|
||||||
|
post_op_fh3 obj;
|
||||||
|
post_op_attr obj_attributes;
|
||||||
|
wcc_data dir_wcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SYMLINK3resfail {
|
||||||
|
wcc_data dir_wcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
union SYMLINK3res switch (nfsstat3 status) {
|
||||||
|
case NFS3_OK:
|
||||||
|
SYMLINK3resok resok;
|
||||||
|
default:
|
||||||
|
SYMLINK3resfail resfail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct devicedata3 {
|
||||||
|
sattr3 dev_attributes;
|
||||||
|
specdata3 spec;
|
||||||
|
};
|
||||||
|
|
||||||
|
union mknoddata3 switch (ftype3 type) {
|
||||||
|
case NFS3CHR:
|
||||||
|
case NFS3BLK:
|
||||||
|
devicedata3 device;
|
||||||
|
case NFS3SOCK:
|
||||||
|
case NFS3FIFO:
|
||||||
|
sattr3 pipe_attributes;
|
||||||
|
default:
|
||||||
|
void;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MKNOD3args {
|
||||||
|
diropargs3 where;
|
||||||
|
mknoddata3 what;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MKNOD3resok {
|
||||||
|
post_op_fh3 obj;
|
||||||
|
post_op_attr obj_attributes;
|
||||||
|
wcc_data dir_wcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MKNOD3resfail {
|
||||||
|
wcc_data dir_wcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
union MKNOD3res switch (nfsstat3 status) {
|
||||||
|
case NFS3_OK:
|
||||||
|
MKNOD3resok resok;
|
||||||
|
default:
|
||||||
|
MKNOD3resfail resfail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct REMOVE3args {
|
||||||
|
diropargs3 object;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct REMOVE3resok {
|
||||||
|
wcc_data dir_wcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct REMOVE3resfail {
|
||||||
|
wcc_data dir_wcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
union REMOVE3res switch (nfsstat3 status) {
|
||||||
|
case NFS3_OK:
|
||||||
|
REMOVE3resok resok;
|
||||||
|
default:
|
||||||
|
REMOVE3resfail resfail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RMDIR3args {
|
||||||
|
diropargs3 object;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RMDIR3resok {
|
||||||
|
wcc_data dir_wcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RMDIR3resfail {
|
||||||
|
wcc_data dir_wcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
union RMDIR3res switch (nfsstat3 status) {
|
||||||
|
case NFS3_OK:
|
||||||
|
RMDIR3resok resok;
|
||||||
|
default:
|
||||||
|
RMDIR3resfail resfail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RENAME3args {
|
||||||
|
diropargs3 from;
|
||||||
|
diropargs3 to;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RENAME3resok {
|
||||||
|
wcc_data fromdir_wcc;
|
||||||
|
wcc_data todir_wcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RENAME3resfail {
|
||||||
|
wcc_data fromdir_wcc;
|
||||||
|
wcc_data todir_wcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
union RENAME3res switch (nfsstat3 status) {
|
||||||
|
case NFS3_OK:
|
||||||
|
RENAME3resok resok;
|
||||||
|
default:
|
||||||
|
RENAME3resfail resfail;
|
||||||
|
};
|
||||||
|
struct LINK3args {
|
||||||
|
nfs_fh3 file;
|
||||||
|
diropargs3 link;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LINK3resok {
|
||||||
|
post_op_attr file_attributes;
|
||||||
|
wcc_data linkdir_wcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LINK3resfail {
|
||||||
|
post_op_attr file_attributes;
|
||||||
|
wcc_data linkdir_wcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
union LINK3res switch (nfsstat3 status) {
|
||||||
|
case NFS3_OK:
|
||||||
|
LINK3resok resok;
|
||||||
|
default:
|
||||||
|
LINK3resfail resfail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct READDIR3args {
|
||||||
|
nfs_fh3 dir;
|
||||||
|
cookie3 cookie;
|
||||||
|
cookieverf3 cookieverf;
|
||||||
|
count3 count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct entry3 {
|
||||||
|
fileid3 fileid;
|
||||||
|
filename3 name;
|
||||||
|
cookie3 cookie;
|
||||||
|
entry3 *nextentry;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dirlist3 {
|
||||||
|
entry3 *entries;
|
||||||
|
bool eof;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct READDIR3resok {
|
||||||
|
post_op_attr dir_attributes;
|
||||||
|
cookieverf3 cookieverf;
|
||||||
|
dirlist3 reply;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct READDIR3resfail {
|
||||||
|
post_op_attr dir_attributes;
|
||||||
|
};
|
||||||
|
|
||||||
|
union READDIR3res switch (nfsstat3 status) {
|
||||||
|
case NFS3_OK:
|
||||||
|
READDIR3resok resok;
|
||||||
|
default:
|
||||||
|
READDIR3resfail resfail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct READDIRPLUS3args {
|
||||||
|
nfs_fh3 dir;
|
||||||
|
cookie3 cookie;
|
||||||
|
cookieverf3 cookieverf;
|
||||||
|
count3 dircount;
|
||||||
|
count3 maxcount;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct entryplus3 {
|
||||||
|
fileid3 fileid;
|
||||||
|
filename3 name;
|
||||||
|
cookie3 cookie;
|
||||||
|
post_op_attr name_attributes;
|
||||||
|
post_op_fh3 name_handle;
|
||||||
|
entryplus3 *nextentry;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dirlistplus3 {
|
||||||
|
entryplus3 *entries;
|
||||||
|
bool eof;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct READDIRPLUS3resok {
|
||||||
|
post_op_attr dir_attributes;
|
||||||
|
cookieverf3 cookieverf;
|
||||||
|
dirlistplus3 reply;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct READDIRPLUS3resfail {
|
||||||
|
post_op_attr dir_attributes;
|
||||||
|
};
|
||||||
|
|
||||||
|
union READDIRPLUS3res switch (nfsstat3 status) {
|
||||||
|
case NFS3_OK:
|
||||||
|
READDIRPLUS3resok resok;
|
||||||
|
default:
|
||||||
|
READDIRPLUS3resfail resfail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FSSTAT3args {
|
||||||
|
nfs_fh3 fsroot;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FSSTAT3resok {
|
||||||
|
post_op_attr obj_attributes;
|
||||||
|
size3 tbytes;
|
||||||
|
size3 fbytes;
|
||||||
|
size3 abytes;
|
||||||
|
size3 tfiles;
|
||||||
|
size3 ffiles;
|
||||||
|
size3 afiles;
|
||||||
|
uint32 invarsec;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FSSTAT3resfail {
|
||||||
|
post_op_attr obj_attributes;
|
||||||
|
};
|
||||||
|
|
||||||
|
union FSSTAT3res switch (nfsstat3 status) {
|
||||||
|
case NFS3_OK:
|
||||||
|
FSSTAT3resok resok;
|
||||||
|
default:
|
||||||
|
FSSTAT3resfail resfail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FSINFO3args {
|
||||||
|
nfs_fh3 fsroot;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FSINFO3resok {
|
||||||
|
post_op_attr obj_attributes;
|
||||||
|
uint32 rtmax;
|
||||||
|
uint32 rtpref;
|
||||||
|
uint32 rtmult;
|
||||||
|
uint32 wtmax;
|
||||||
|
uint32 wtpref;
|
||||||
|
uint32 wtmult;
|
||||||
|
uint32 dtpref;
|
||||||
|
size3 maxfilesize;
|
||||||
|
nfstime3 time_delta;
|
||||||
|
uint32 properties;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FSINFO3resfail {
|
||||||
|
post_op_attr obj_attributes;
|
||||||
|
};
|
||||||
|
|
||||||
|
union FSINFO3res switch (nfsstat3 status) {
|
||||||
|
case NFS3_OK:
|
||||||
|
FSINFO3resok resok;
|
||||||
|
default:
|
||||||
|
FSINFO3resfail resfail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PATHCONF3args {
|
||||||
|
nfs_fh3 object;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PATHCONF3resok {
|
||||||
|
post_op_attr obj_attributes;
|
||||||
|
uint32 linkmax;
|
||||||
|
uint32 name_max;
|
||||||
|
bool no_trunc;
|
||||||
|
bool chown_restricted;
|
||||||
|
bool case_insensitive;
|
||||||
|
bool case_preserving;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PATHCONF3resfail {
|
||||||
|
post_op_attr obj_attributes;
|
||||||
|
};
|
||||||
|
|
||||||
|
union PATHCONF3res switch (nfsstat3 status) {
|
||||||
|
case NFS3_OK:
|
||||||
|
PATHCONF3resok resok;
|
||||||
|
default:
|
||||||
|
PATHCONF3resfail resfail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct COMMIT3args {
|
||||||
|
nfs_fh3 file;
|
||||||
|
offset3 offset;
|
||||||
|
count3 count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct COMMIT3resok {
|
||||||
|
wcc_data file_wcc;
|
||||||
|
writeverf3 verf;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct COMMIT3resfail {
|
||||||
|
wcc_data file_wcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
union COMMIT3res switch (nfsstat3 status) {
|
||||||
|
case NFS3_OK:
|
||||||
|
COMMIT3resok resok;
|
||||||
|
default:
|
||||||
|
COMMIT3resfail resfail;
|
||||||
|
};
|
||||||
|
|
||||||
|
program NFS_PROGRAM {
|
||||||
|
version NFS_V3 {
|
||||||
|
void NFSPROC3_NULL(void) = 0;
|
||||||
|
GETATTR3res NFSPROC3_GETATTR(GETATTR3args) = 1;
|
||||||
|
SETATTR3res NFSPROC3_SETATTR(SETATTR3args) = 2;
|
||||||
|
LOOKUP3res NFSPROC3_LOOKUP(LOOKUP3args) = 3;
|
||||||
|
ACCESS3res NFSPROC3_ACCESS(ACCESS3args) = 4;
|
||||||
|
READLINK3res NFSPROC3_READLINK(READLINK3args) = 5;
|
||||||
|
READ3res NFSPROC3_READ(READ3args) = 6;
|
||||||
|
WRITE3res NFSPROC3_WRITE(WRITE3args) = 7;
|
||||||
|
CREATE3res NFSPROC3_CREATE(CREATE3args) = 8;
|
||||||
|
MKDIR3res NFSPROC3_MKDIR(MKDIR3args) = 9;
|
||||||
|
SYMLINK3res NFSPROC3_SYMLINK(SYMLINK3args) = 10;
|
||||||
|
MKNOD3res NFSPROC3_MKNOD(MKNOD3args) = 11;
|
||||||
|
REMOVE3res NFSPROC3_REMOVE(REMOVE3args) = 12;
|
||||||
|
RMDIR3res NFSPROC3_RMDIR(RMDIR3args) = 13;
|
||||||
|
RENAME3res NFSPROC3_RENAME(RENAME3args) = 14;
|
||||||
|
LINK3res NFSPROC3_LINK(LINK3args) = 15;
|
||||||
|
READDIR3res NFSPROC3_READDIR(READDIR3args) = 16;
|
||||||
|
READDIRPLUS3res NFSPROC3_READDIRPLUS(READDIRPLUS3args) = 17;
|
||||||
|
FSSTAT3res NFSPROC3_FSSTAT(FSSTAT3args) = 18;
|
||||||
|
FSINFO3res NFSPROC3_FSINFO(FSINFO3args) = 19;
|
||||||
|
PATHCONF3res NFSPROC3_PATHCONF(PATHCONF3args) = 20;
|
||||||
|
COMMIT3res NFSPROC3_COMMIT(COMMIT3args) = 21;
|
||||||
|
} = 3;
|
||||||
|
} = 100003;
|
172
components/dfs/dfs_v1/filesystems/nfs/nfs_auth.c
Normal file
172
components/dfs/dfs_v1/filesystems/nfs/nfs_auth.c
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rpc/types.h>
|
||||||
|
#include <rpc/xdr.h>
|
||||||
|
#include <rpc/auth.h>
|
||||||
|
|
||||||
|
#define MAX_MARSHEL_SIZE 64
|
||||||
|
|
||||||
|
struct nfs_credentia
|
||||||
|
{
|
||||||
|
rt_uint32_t stamp;
|
||||||
|
char *name;
|
||||||
|
rt_uint32_t uid;
|
||||||
|
rt_uint32_t gid;
|
||||||
|
rt_uint32_t *auxi;
|
||||||
|
rt_uint32_t auxi_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void authnone_verf(AUTH *);
|
||||||
|
static bool_t authnone_validate(AUTH *, struct opaque_auth *);
|
||||||
|
static bool_t authnone_refresh(AUTH *);
|
||||||
|
static void authnone_destroy(AUTH *);
|
||||||
|
static bool_t authnone_marshal(AUTH *client, XDR *xdrs);
|
||||||
|
|
||||||
|
static struct nfs_credentia _credentia = {
|
||||||
|
.stamp = 0,
|
||||||
|
.name = "rt-thread",
|
||||||
|
.uid = 0,
|
||||||
|
.gid = 0,
|
||||||
|
.auxi = NULL,
|
||||||
|
.auxi_count = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct opaque_auth _null_auth;
|
||||||
|
|
||||||
|
static struct auth_ops ops =
|
||||||
|
{
|
||||||
|
authnone_verf,
|
||||||
|
authnone_marshal,
|
||||||
|
authnone_validate,
|
||||||
|
authnone_refresh,
|
||||||
|
authnone_destroy
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct authnone_private
|
||||||
|
{
|
||||||
|
AUTH no_client;
|
||||||
|
char marshalled_client[MAX_MARSHEL_SIZE];
|
||||||
|
unsigned int mcnt;
|
||||||
|
} *authnone_private;
|
||||||
|
|
||||||
|
AUTH *authnone_create(void)
|
||||||
|
{
|
||||||
|
register struct authnone_private *ap = authnone_private;
|
||||||
|
XDR xdr_stream;
|
||||||
|
register XDR *xdrs;
|
||||||
|
extern bool_t xdr_opaque_auth(XDR * xdrs, struct opaque_auth * ap);
|
||||||
|
struct opaque_auth auth;
|
||||||
|
rt_uint32_t *auth_buf, *auth_base;
|
||||||
|
int buf_len = 0, str_len = 0;
|
||||||
|
|
||||||
|
if (_credentia.name)
|
||||||
|
{
|
||||||
|
str_len = strlen(_credentia.name);
|
||||||
|
}
|
||||||
|
if (str_len == 0)
|
||||||
|
{
|
||||||
|
_credentia.name = "unknown";
|
||||||
|
str_len = strlen(_credentia.name);
|
||||||
|
}
|
||||||
|
buf_len = ((str_len) + (sizeof(rt_uint32_t)) - 1) & ~((sizeof(rt_uint32_t)) - 1);
|
||||||
|
buf_len += sizeof(struct nfs_credentia);
|
||||||
|
if (_credentia.auxi && _credentia.auxi_count)
|
||||||
|
{
|
||||||
|
buf_len += sizeof(rt_uint32_t) * _credentia.auxi_count;
|
||||||
|
}
|
||||||
|
auth_buf = auth_base = rt_malloc(buf_len);
|
||||||
|
if (auth_buf == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(auth_buf, 0, buf_len);
|
||||||
|
*auth_buf++ = htonl(rt_tick_get());
|
||||||
|
*auth_buf++ = htonl(str_len);
|
||||||
|
memcpy(auth_buf, _credentia.name, str_len);
|
||||||
|
auth_buf += (str_len + sizeof(rt_uint32_t) - 1) >> 2;
|
||||||
|
*auth_buf++ = htonl(_credentia.uid);
|
||||||
|
*auth_buf++ = htonl(_credentia.gid);
|
||||||
|
if (_credentia.auxi && _credentia.auxi_count)
|
||||||
|
{
|
||||||
|
rt_uint32_t tmp_cnt = 0;
|
||||||
|
*auth_buf++ = htonl(_credentia.auxi_count);
|
||||||
|
while (tmp_cnt < _credentia.auxi_count)
|
||||||
|
{
|
||||||
|
*auth_buf++ = htonl(_credentia.auxi[tmp_cnt]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*auth_buf++ = htonl(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ap == 0)
|
||||||
|
{
|
||||||
|
ap = (struct authnone_private *) rt_malloc(sizeof(*ap));
|
||||||
|
if (ap == 0)
|
||||||
|
{
|
||||||
|
rt_free(auth_base);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(ap, 0, sizeof(*ap));
|
||||||
|
authnone_private = ap;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ap->mcnt)
|
||||||
|
{
|
||||||
|
memset(&auth, 0, sizeof(auth));
|
||||||
|
auth.oa_flavor = 1;
|
||||||
|
auth.oa_base = (char *)auth_base;
|
||||||
|
auth.oa_length = (auth_buf - auth_base) * sizeof(rt_uint32_t);
|
||||||
|
ap->no_client.ah_cred = auth;
|
||||||
|
ap->no_client.ah_verf = _null_auth;
|
||||||
|
ap->no_client.ah_ops = &ops;
|
||||||
|
xdrs = &xdr_stream;
|
||||||
|
xdrmem_create(xdrs, ap->marshalled_client,
|
||||||
|
(unsigned int) MAX_MARSHEL_SIZE, XDR_ENCODE);
|
||||||
|
(void) xdr_opaque_auth(xdrs, &ap->no_client.ah_cred);
|
||||||
|
(void) xdr_opaque_auth(xdrs, &ap->no_client.ah_verf);
|
||||||
|
ap->mcnt = XDR_GETPOS(xdrs);
|
||||||
|
XDR_DESTROY(xdrs);
|
||||||
|
}
|
||||||
|
rt_free(auth_base);
|
||||||
|
return (&ap->no_client);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
static bool_t authnone_marshal(AUTH *client, XDR *xdrs)
|
||||||
|
{
|
||||||
|
register struct authnone_private *ap = authnone_private;
|
||||||
|
|
||||||
|
if (ap == 0)
|
||||||
|
return (0);
|
||||||
|
return ((*xdrs->x_ops->x_putbytes)(xdrs,
|
||||||
|
ap->marshalled_client, ap->mcnt));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void authnone_verf(AUTH *x)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t authnone_validate(AUTH *x, struct opaque_auth *x1)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t authnone_refresh(AUTH *x)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void authnone_destroy(AUTH *x)
|
||||||
|
{
|
||||||
|
}
|
222
components/dfs/dfs_v1/filesystems/nfs/nfs_clnt.c
Normal file
222
components/dfs/dfs_v1/filesystems/nfs/nfs_clnt.c
Normal file
|
@ -0,0 +1,222 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Please do not edit this file.
|
||||||
|
* It was generated using rpcgen.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h> /* for memset */
|
||||||
|
#include "nfs.h"
|
||||||
|
|
||||||
|
/* This file is copied from RFC1813
|
||||||
|
* Copyright 1995 Sun Micrososystems (I assume)
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef char* caddr_t;
|
||||||
|
|
||||||
|
/* Default timeout can be changed using clnt_control() */
|
||||||
|
static struct timeval TIMEOUT = { 25, 0 };
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
nfsproc3_null_3(void *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, NFSPROC3_NULL,
|
||||||
|
(xdrproc_t) xdr_void, (caddr_t) NULL,
|
||||||
|
(xdrproc_t) xdr_void, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
nfsproc3_getattr_3(GETATTR3args arg1, GETATTR3res *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, NFSPROC3_GETATTR,
|
||||||
|
(xdrproc_t) xdr_GETATTR3args, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_GETATTR3res, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
nfsproc3_setattr_3(SETATTR3args arg1, SETATTR3res *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, NFSPROC3_SETATTR,
|
||||||
|
(xdrproc_t) xdr_SETATTR3args, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_SETATTR3res, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
nfsproc3_lookup_3(LOOKUP3args arg1, LOOKUP3res *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, NFSPROC3_LOOKUP,
|
||||||
|
(xdrproc_t) xdr_LOOKUP3args, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_LOOKUP3res, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
nfsproc3_access_3(ACCESS3args arg1, ACCESS3res *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, NFSPROC3_ACCESS,
|
||||||
|
(xdrproc_t) xdr_ACCESS3args, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_ACCESS3res, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
nfsproc3_readlink_3(READLINK3args arg1, READLINK3res *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, NFSPROC3_READLINK,
|
||||||
|
(xdrproc_t) xdr_READLINK3args, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_READLINK3res, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
nfsproc3_read_3(READ3args arg1, READ3res *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, NFSPROC3_READ,
|
||||||
|
(xdrproc_t) xdr_READ3args, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_READ3res, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
nfsproc3_write_3(WRITE3args arg1, WRITE3res *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, NFSPROC3_WRITE,
|
||||||
|
(xdrproc_t) xdr_WRITE3args, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_WRITE3res, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
nfsproc3_create_3(CREATE3args arg1, CREATE3res *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, NFSPROC3_CREATE,
|
||||||
|
(xdrproc_t) xdr_CREATE3args, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_CREATE3res, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
nfsproc3_mkdir_3(MKDIR3args arg1, MKDIR3res *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, NFSPROC3_MKDIR,
|
||||||
|
(xdrproc_t) xdr_MKDIR3args, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_MKDIR3res, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
nfsproc3_symlink_3(SYMLINK3args arg1, SYMLINK3res *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, NFSPROC3_SYMLINK,
|
||||||
|
(xdrproc_t) xdr_SYMLINK3args, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_SYMLINK3res, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
nfsproc3_mknod_3(MKNOD3args arg1, MKNOD3res *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, NFSPROC3_MKNOD,
|
||||||
|
(xdrproc_t) xdr_MKNOD3args, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_MKNOD3res, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
nfsproc3_remove_3(REMOVE3args arg1, REMOVE3res *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, NFSPROC3_REMOVE,
|
||||||
|
(xdrproc_t) xdr_REMOVE3args, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_REMOVE3res, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
nfsproc3_rmdir_3(RMDIR3args arg1, RMDIR3res *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, NFSPROC3_RMDIR,
|
||||||
|
(xdrproc_t) xdr_RMDIR3args, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_RMDIR3res, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
nfsproc3_rename_3(RENAME3args arg1, RENAME3res *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, NFSPROC3_RENAME,
|
||||||
|
(xdrproc_t) xdr_RENAME3args, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_RENAME3res, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
nfsproc3_link_3(LINK3args arg1, LINK3res *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, NFSPROC3_LINK,
|
||||||
|
(xdrproc_t) xdr_LINK3args, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_LINK3res, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
nfsproc3_readdir_3(READDIR3args arg1, READDIR3res *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, NFSPROC3_READDIR,
|
||||||
|
(xdrproc_t) xdr_READDIR3args, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_READDIR3res, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
nfsproc3_readdirplus_3(READDIRPLUS3args arg1, READDIRPLUS3res *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, NFSPROC3_READDIRPLUS,
|
||||||
|
(xdrproc_t) xdr_READDIRPLUS3args, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_READDIRPLUS3res, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
nfsproc3_fsstat_3(FSSTAT3args arg1, FSSTAT3res *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, NFSPROC3_FSSTAT,
|
||||||
|
(xdrproc_t) xdr_FSSTAT3args, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_FSSTAT3res, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
nfsproc3_fsinfo_3(FSINFO3args arg1, FSINFO3res *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, NFSPROC3_FSINFO,
|
||||||
|
(xdrproc_t) xdr_FSINFO3args, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_FSINFO3res, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
nfsproc3_pathconf_3(PATHCONF3args arg1, PATHCONF3res *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, NFSPROC3_PATHCONF,
|
||||||
|
(xdrproc_t) xdr_PATHCONF3args, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_PATHCONF3res, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
nfsproc3_commit_3(COMMIT3args arg1, COMMIT3res *clnt_res, CLIENT *clnt)
|
||||||
|
{
|
||||||
|
return (clnt_call(clnt, NFSPROC3_COMMIT,
|
||||||
|
(xdrproc_t) xdr_COMMIT3args, (caddr_t) &arg1,
|
||||||
|
(xdrproc_t) xdr_COMMIT3res, (caddr_t) clnt_res,
|
||||||
|
TIMEOUT));
|
||||||
|
}
|
1622
components/dfs/dfs_v1/filesystems/nfs/nfs_xdr.c
Normal file
1622
components/dfs/dfs_v1/filesystems/nfs/nfs_xdr.c
Normal file
File diff suppressed because it is too large
Load diff
112
components/dfs/dfs_v1/filesystems/nfs/rpc/auth.h
Normal file
112
components/dfs/dfs_v1/filesystems/nfs/rpc/auth.h
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
#ifndef __AUTH_H__
|
||||||
|
#define __AUTH_H__
|
||||||
|
|
||||||
|
#include <rpc/xdr.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Status returned from authentication check
|
||||||
|
*/
|
||||||
|
enum auth_stat {
|
||||||
|
AUTH_OK=0,
|
||||||
|
/*
|
||||||
|
* failed at remote end
|
||||||
|
*/
|
||||||
|
AUTH_BADCRED=1, /* bogus credentials (seal broken) */
|
||||||
|
AUTH_REJECTEDCRED=2, /* client should begin new session */
|
||||||
|
AUTH_BADVERF=3, /* bogus verifier (seal broken) */
|
||||||
|
AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */
|
||||||
|
AUTH_TOOWEAK=5, /* rejected due to security reasons */
|
||||||
|
/*
|
||||||
|
* failed locally
|
||||||
|
*/
|
||||||
|
AUTH_INVALIDRESP=6, /* bogus response verifier */
|
||||||
|
AUTH_FAILED=7 /* some unknown reason */
|
||||||
|
};
|
||||||
|
|
||||||
|
union des_block {
|
||||||
|
struct {
|
||||||
|
uint32_t high;
|
||||||
|
uint32_t low;
|
||||||
|
} key;
|
||||||
|
char c[8];
|
||||||
|
};
|
||||||
|
typedef union des_block des_block;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Authentication info. Opaque to client.
|
||||||
|
*/
|
||||||
|
struct opaque_auth {
|
||||||
|
enum_t oa_flavor; /* flavor of auth */
|
||||||
|
char* oa_base; /* address of more auth stuff */
|
||||||
|
unsigned int oa_length; /* not to exceed MAX_AUTH_BYTES */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Auth handle, interface to client side authenticators.
|
||||||
|
*/
|
||||||
|
typedef struct AUTH AUTH;
|
||||||
|
struct AUTH {
|
||||||
|
struct opaque_auth ah_cred;
|
||||||
|
struct opaque_auth ah_verf;
|
||||||
|
union des_block ah_key;
|
||||||
|
struct auth_ops {
|
||||||
|
void (*ah_nextverf) (AUTH *);
|
||||||
|
int (*ah_marshal) (AUTH *, XDR *); /* nextverf & serialize */
|
||||||
|
int (*ah_validate) (AUTH *, struct opaque_auth *);
|
||||||
|
/* validate verifier */
|
||||||
|
int (*ah_refresh) (AUTH *); /* refresh credentials */
|
||||||
|
void (*ah_destroy) (AUTH *); /* destroy this structure */
|
||||||
|
} *ah_ops;
|
||||||
|
char* ah_private;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct opaque_auth _null_auth;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Authentication ops.
|
||||||
|
* The ops and the auth handle provide the interface to the authenticators.
|
||||||
|
*
|
||||||
|
* AUTH *auth;
|
||||||
|
* XDR *xdrs;
|
||||||
|
* struct opaque_auth verf;
|
||||||
|
*/
|
||||||
|
#define AUTH_NEXTVERF(auth) \
|
||||||
|
((*((auth)->ah_ops->ah_nextverf))(auth))
|
||||||
|
#define auth_nextverf(auth) \
|
||||||
|
((*((auth)->ah_ops->ah_nextverf))(auth))
|
||||||
|
|
||||||
|
#define AUTH_MARSHALL(auth, xdrs) \
|
||||||
|
((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
|
||||||
|
#define auth_marshall(auth, xdrs) \
|
||||||
|
((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
|
||||||
|
|
||||||
|
#define AUTH_VALIDATE(auth, verfp) \
|
||||||
|
((*((auth)->ah_ops->ah_validate))((auth), verfp))
|
||||||
|
#define auth_validate(auth, verfp) \
|
||||||
|
((*((auth)->ah_ops->ah_validate))((auth), verfp))
|
||||||
|
|
||||||
|
#define AUTH_REFRESH(auth) \
|
||||||
|
((*((auth)->ah_ops->ah_refresh))(auth))
|
||||||
|
#define auth_refresh(auth) \
|
||||||
|
((*((auth)->ah_ops->ah_refresh))(auth))
|
||||||
|
|
||||||
|
#define AUTH_DESTROY(auth) \
|
||||||
|
((*((auth)->ah_ops->ah_destroy))(auth))
|
||||||
|
#define auth_destroy(auth) \
|
||||||
|
((*((auth)->ah_ops->ah_destroy))(auth))
|
||||||
|
|
||||||
|
#define MAX_AUTH_BYTES 400
|
||||||
|
#define MAXNETNAMELEN 255 /* maximum length of network user's name */
|
||||||
|
|
||||||
|
AUTH *authnone_create(void);
|
||||||
|
|
||||||
|
#endif
|
135
components/dfs/dfs_v1/filesystems/nfs/rpc/auth_none.c
Normal file
135
components/dfs/dfs_v1/filesystems/nfs/rpc/auth_none.c
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
/* @(#)auth_none.c 2.1 88/07/29 4.0 RPCSRC */
|
||||||
|
/*
|
||||||
|
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||||
|
* unrestricted use provided that this legend is included on all tape
|
||||||
|
* media and as a part of the software program in whole or part. Users
|
||||||
|
* may copy or modify Sun RPC without charge, but are not authorized
|
||||||
|
* to license or distribute it to anyone else except as part of a product or
|
||||||
|
* program developed by the user.
|
||||||
|
*
|
||||||
|
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||||
|
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||||
|
*
|
||||||
|
* Sun RPC is provided with no support and without any obligation on the
|
||||||
|
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||||
|
* modification or enhancement.
|
||||||
|
*
|
||||||
|
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||||
|
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||||
|
* OR ANY PART THEREOF.
|
||||||
|
*
|
||||||
|
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||||
|
* or profits or other special, indirect and consequential damages, even if
|
||||||
|
* Sun has been advised of the possibility of such damages.
|
||||||
|
*
|
||||||
|
* Sun Microsystems, Inc.
|
||||||
|
* 2550 Garcia Avenue
|
||||||
|
* Mountain View, California 94043
|
||||||
|
*/
|
||||||
|
#if !defined(lint) && defined(SCCSIDS)
|
||||||
|
static char sccsid[] =
|
||||||
|
|
||||||
|
"@(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* auth_none.c
|
||||||
|
* Creates a client authentication handle for passing "null"
|
||||||
|
* credentials and verifiers to remote systems.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rpc/types.h>
|
||||||
|
#include <rpc/xdr.h>
|
||||||
|
#include <rpc/auth.h>
|
||||||
|
#define MAX_MARSHEL_SIZE 20
|
||||||
|
|
||||||
|
static void authnone_verf(AUTH *);
|
||||||
|
static bool_t authnone_validate(AUTH *, struct opaque_auth *);
|
||||||
|
static bool_t authnone_refresh(AUTH *);
|
||||||
|
static void authnone_destroy(AUTH *);
|
||||||
|
static bool_t authnone_marshal(AUTH *client, XDR *xdrs);
|
||||||
|
|
||||||
|
struct opaque_auth _null_auth;
|
||||||
|
|
||||||
|
static struct auth_ops ops = {
|
||||||
|
authnone_verf,
|
||||||
|
authnone_marshal,
|
||||||
|
authnone_validate,
|
||||||
|
authnone_refresh,
|
||||||
|
authnone_destroy
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct authnone_private {
|
||||||
|
AUTH no_client;
|
||||||
|
char marshalled_client[MAX_MARSHEL_SIZE];
|
||||||
|
unsigned int mcnt;
|
||||||
|
} *authnone_private;
|
||||||
|
|
||||||
|
AUTH *authnone_create()
|
||||||
|
{
|
||||||
|
register struct authnone_private *ap = authnone_private;
|
||||||
|
XDR xdr_stream;
|
||||||
|
register XDR *xdrs;
|
||||||
|
extern bool_t xdr_opaque_auth(XDR *xdrs, struct opaque_auth *ap);
|
||||||
|
|
||||||
|
if (ap == 0) {
|
||||||
|
ap = (struct authnone_private *) rt_malloc (sizeof(*ap));
|
||||||
|
if (ap == 0) return NULL;
|
||||||
|
memset(ap, 0, sizeof(*ap));
|
||||||
|
authnone_private = ap;
|
||||||
|
}
|
||||||
|
if (!ap->mcnt) {
|
||||||
|
ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth;
|
||||||
|
ap->no_client.ah_ops = &ops;
|
||||||
|
xdrs = &xdr_stream;
|
||||||
|
xdrmem_create(xdrs, ap->marshalled_client,
|
||||||
|
(unsigned int) MAX_MARSHEL_SIZE, XDR_ENCODE);
|
||||||
|
(void) xdr_opaque_auth(xdrs, &ap->no_client.ah_cred);
|
||||||
|
(void) xdr_opaque_auth(xdrs, &ap->no_client.ah_verf);
|
||||||
|
ap->mcnt = XDR_GETPOS(xdrs);
|
||||||
|
XDR_DESTROY(xdrs);
|
||||||
|
}
|
||||||
|
return (&ap->no_client);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
static bool_t authnone_marshal(AUTH *client, XDR *xdrs)
|
||||||
|
{
|
||||||
|
register struct authnone_private *ap = authnone_private;
|
||||||
|
|
||||||
|
if (ap == 0)
|
||||||
|
return (0);
|
||||||
|
return ((*xdrs->x_ops->x_putbytes) (xdrs,
|
||||||
|
ap->marshalled_client, ap->mcnt));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void authnone_verf(AUTH *x)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t authnone_validate(AUTH *x, struct opaque_auth *x1)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t authnone_refresh(AUTH *x)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void authnone_destroy(AUTH *x)
|
||||||
|
{
|
||||||
|
}
|
330
components/dfs/dfs_v1/filesystems/nfs/rpc/clnt.h
Normal file
330
components/dfs/dfs_v1/filesystems/nfs/rpc/clnt.h
Normal file
|
@ -0,0 +1,330 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
/* @(#)clnt.h 2.1 88/07/29 4.0 RPCSRC; from 1.31 88/02/08 SMI*/
|
||||||
|
/*
|
||||||
|
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||||
|
* unrestricted use provided that this legend is included on all tape
|
||||||
|
* media and as a part of the software program in whole or part. Users
|
||||||
|
* may copy or modify Sun RPC without charge, but are not authorized
|
||||||
|
* to license or distribute it to anyone else except as part of a product or
|
||||||
|
* program developed by the user.
|
||||||
|
*
|
||||||
|
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||||
|
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||||
|
*
|
||||||
|
* Sun RPC is provided with no support and without any obligation on the
|
||||||
|
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||||
|
* modification or enhancement.
|
||||||
|
*
|
||||||
|
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||||
|
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||||
|
* OR ANY PART THEREOF.
|
||||||
|
*
|
||||||
|
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||||
|
* or profits or other special, indirect and consequential damages, even if
|
||||||
|
* Sun has been advised of the possibility of such damages.
|
||||||
|
*
|
||||||
|
* Sun Microsystems, Inc.
|
||||||
|
* 2550 Garcia Avenue
|
||||||
|
* Mountain View, California 94043
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* clnt.h - Client side remote procedure call interface.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RPC_CLNT_H
|
||||||
|
#define _RPC_CLNT_H 1
|
||||||
|
|
||||||
|
#include <rpc/types.h>
|
||||||
|
#include <rpc/auth.h>
|
||||||
|
#include <lwip/sockets.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Rpc calls return an enum clnt_stat. This should be looked at more,
|
||||||
|
* since each implementation is required to live with this (implementation
|
||||||
|
* independent) list of errors.
|
||||||
|
*/
|
||||||
|
enum clnt_stat {
|
||||||
|
RPC_SUCCESS=0, /* call succeeded */
|
||||||
|
/*
|
||||||
|
* local errors
|
||||||
|
*/
|
||||||
|
RPC_CANTENCODEARGS=1, /* can't encode arguments */
|
||||||
|
RPC_CANTDECODERES=2, /* can't decode results */
|
||||||
|
RPC_CANTSEND=3, /* failure in sending call */
|
||||||
|
RPC_CANTRECV=4, /* failure in receiving result */
|
||||||
|
RPC_TIMEDOUT=5, /* call timed out */
|
||||||
|
/*
|
||||||
|
* remote errors
|
||||||
|
*/
|
||||||
|
RPC_VERSMISMATCH=6, /* rpc versions not compatible */
|
||||||
|
RPC_AUTHERROR=7, /* authentication error */
|
||||||
|
RPC_PROGUNAVAIL=8, /* program not available */
|
||||||
|
RPC_PROGVERSMISMATCH=9, /* program version mismatched */
|
||||||
|
RPC_PROCUNAVAIL=10, /* procedure unavailable */
|
||||||
|
RPC_CANTDECODEARGS=11, /* decode arguments error */
|
||||||
|
RPC_SYSTEMERROR=12, /* generic "other problem" */
|
||||||
|
RPC_NOBROADCAST = 21, /* Broadcasting not supported */
|
||||||
|
/*
|
||||||
|
* callrpc & clnt_create errors
|
||||||
|
*/
|
||||||
|
RPC_UNKNOWNHOST=13, /* unknown host name */
|
||||||
|
RPC_UNKNOWNPROTO=17, /* unknown protocol */
|
||||||
|
RPC_UNKNOWNADDR = 19, /* Remote address unknown */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rpcbind errors
|
||||||
|
*/
|
||||||
|
RPC_RPCBFAILURE=14, /* portmapper failed in its call */
|
||||||
|
#define RPC_PMAPFAILURE RPC_RPCBFAILURE
|
||||||
|
RPC_PROGNOTREGISTERED=15, /* remote program is not registered */
|
||||||
|
RPC_N2AXLATEFAILURE = 22, /* Name to addr translation failed */
|
||||||
|
/*
|
||||||
|
* unspecified error
|
||||||
|
*/
|
||||||
|
RPC_FAILED=16,
|
||||||
|
RPC_INTR=18,
|
||||||
|
RPC_TLIERROR=20,
|
||||||
|
RPC_UDERROR=23,
|
||||||
|
/*
|
||||||
|
* asynchronous errors
|
||||||
|
*/
|
||||||
|
RPC_INPROGRESS = 24,
|
||||||
|
RPC_STALERACHANDLE = 25
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Error info.
|
||||||
|
*/
|
||||||
|
struct rpc_err {
|
||||||
|
int re_status;
|
||||||
|
union {
|
||||||
|
int RE_errno; /* related system error */
|
||||||
|
int RE_why; /* why the auth error occurred */
|
||||||
|
struct {
|
||||||
|
unsigned long low; /* lowest verion supported */
|
||||||
|
unsigned long high; /* highest verion supported */
|
||||||
|
} RE_vers;
|
||||||
|
struct { /* maybe meaningful if RPC_FAILED */
|
||||||
|
long s1;
|
||||||
|
long s2;
|
||||||
|
} RE_lb; /* life boot & debugging only */
|
||||||
|
} ru;
|
||||||
|
#define re_errno ru.RE_errno
|
||||||
|
#define re_why ru.RE_why
|
||||||
|
#define re_vers ru.RE_vers
|
||||||
|
#define re_lb ru.RE_lb
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Client rpc handle.
|
||||||
|
* Created by individual implementations, see e.g. rpc_udp.c.
|
||||||
|
* Client is responsible for initializing auth, see e.g. auth_none.c.
|
||||||
|
*/
|
||||||
|
typedef struct CLIENT CLIENT;
|
||||||
|
struct CLIENT {
|
||||||
|
AUTH *cl_auth; /* authenticator */
|
||||||
|
struct clnt_ops {
|
||||||
|
enum clnt_stat (*cl_call) (CLIENT *, unsigned long, xdrproc_t, char*, xdrproc_t,
|
||||||
|
char*, struct timeval);
|
||||||
|
/* call remote procedure */
|
||||||
|
void (*cl_abort) (void); /* abort a call */
|
||||||
|
void (*cl_geterr) (CLIENT *, struct rpc_err *);
|
||||||
|
/* get specific error code */
|
||||||
|
bool_t (*cl_freeres) (CLIENT *, xdrproc_t, char*);
|
||||||
|
/* frees results */
|
||||||
|
void (*cl_destroy) (CLIENT *); /* destroy this structure */
|
||||||
|
bool_t (*cl_control) (CLIENT *, int, char *);
|
||||||
|
/* the ioctl() of rpc */
|
||||||
|
} *cl_ops;
|
||||||
|
char* cl_private; /* private stuff */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* client side rpc interface ops
|
||||||
|
*
|
||||||
|
* Parameter types are:
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* enum clnt_stat
|
||||||
|
* CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout)
|
||||||
|
* CLIENT *rh;
|
||||||
|
* unsigned long proc;
|
||||||
|
* xdrproc_t xargs;
|
||||||
|
* char* argsp;
|
||||||
|
* xdrproc_t xres;
|
||||||
|
* char* resp;
|
||||||
|
* struct timeval timeout;
|
||||||
|
*/
|
||||||
|
#define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs) \
|
||||||
|
((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
|
||||||
|
#define clnt_call(rh, proc, xargs, argsp, xres, resp, secs) \
|
||||||
|
((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* void
|
||||||
|
* CLNT_ABORT(rh);
|
||||||
|
* CLIENT *rh;
|
||||||
|
*/
|
||||||
|
#define CLNT_ABORT(rh) ((*(rh)->cl_ops->cl_abort)(rh))
|
||||||
|
#define clnt_abort(rh) ((*(rh)->cl_ops->cl_abort)(rh))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* struct rpc_err
|
||||||
|
* CLNT_GETERR(rh);
|
||||||
|
* CLIENT *rh;
|
||||||
|
*/
|
||||||
|
#define CLNT_GETERR(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp))
|
||||||
|
#define clnt_geterr(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp))
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* bool_t
|
||||||
|
* CLNT_FREERES(rh, xres, resp);
|
||||||
|
* CLIENT *rh;
|
||||||
|
* xdrproc_t xres;
|
||||||
|
* char* resp;
|
||||||
|
*/
|
||||||
|
#define CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))
|
||||||
|
#define clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* bool_t
|
||||||
|
* CLNT_CONTROL(cl, request, info)
|
||||||
|
* CLIENT *cl;
|
||||||
|
* unsigned int request;
|
||||||
|
* char *info;
|
||||||
|
*/
|
||||||
|
#define CLNT_CONTROL(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
|
||||||
|
#define clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* control operations that apply to all transports
|
||||||
|
*
|
||||||
|
* Note: options marked XXX are no-ops in this implementation of RPC.
|
||||||
|
* The are present in TI-RPC but can't be implemented here since they
|
||||||
|
* depend on the presence of STREAMS/TLI, which we don't have.
|
||||||
|
*/
|
||||||
|
#define CLSET_TIMEOUT 1 /* set timeout (timeval) */
|
||||||
|
#define CLGET_TIMEOUT 2 /* get timeout (timeval) */
|
||||||
|
#define CLGET_SERVER_ADDR 3 /* get server's address (sockaddr) */
|
||||||
|
#define CLGET_FD 6 /* get connections file descriptor */
|
||||||
|
#define CLGET_SVC_ADDR 7 /* get server's address (netbuf) XXX */
|
||||||
|
#define CLSET_FD_CLOSE 8 /* close fd while clnt_destroy */
|
||||||
|
#define CLSET_FD_NCLOSE 9 /* Do not close fd while clnt_destroy*/
|
||||||
|
#define CLGET_XID 10 /* Get xid */
|
||||||
|
#define CLSET_XID 11 /* Set xid */
|
||||||
|
#define CLGET_VERS 12 /* Get version number */
|
||||||
|
#define CLSET_VERS 13 /* Set version number */
|
||||||
|
#define CLGET_PROG 14 /* Get program number */
|
||||||
|
#define CLSET_PROG 15 /* Set program number */
|
||||||
|
#define CLSET_SVC_ADDR 16 /* get server's address (netbuf) XXX */
|
||||||
|
#define CLSET_PUSH_TIMOD 17 /* push timod if not already present XXX */
|
||||||
|
#define CLSET_POP_TIMOD 18 /* pop timod XXX */
|
||||||
|
/*
|
||||||
|
* Connectionless only control operations
|
||||||
|
*/
|
||||||
|
#define CLSET_RETRY_TIMEOUT 4 /* set retry timeout (timeval) */
|
||||||
|
#define CLGET_RETRY_TIMEOUT 5 /* get retry timeout (timeval) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* void
|
||||||
|
* CLNT_DESTROY(rh);
|
||||||
|
* CLIENT *rh;
|
||||||
|
*/
|
||||||
|
#define CLNT_DESTROY(rh) ((*(rh)->cl_ops->cl_destroy)(rh))
|
||||||
|
#define clnt_destroy(rh) ((*(rh)->cl_ops->cl_destroy)(rh))
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RPCTEST is a test program which is accessible on every rpc
|
||||||
|
* transport/port. It is used for testing, performance evaluation,
|
||||||
|
* and network administration.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define RPCTEST_PROGRAM ((unsigned long)1)
|
||||||
|
#define RPCTEST_VERSION ((unsigned long)1)
|
||||||
|
#define RPCTEST_NULL_PROC ((unsigned long)2)
|
||||||
|
#define RPCTEST_NULL_BATCH_PROC ((unsigned long)3)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* By convention, procedure 0 takes null arguments and returns them
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NULLPROC ((unsigned long)0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Below are the client handle creation routines for the various
|
||||||
|
* implementations of client side rpc. They can return NULL if a
|
||||||
|
* creation failure occurs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generic client creation routine. Supported protocols are "udp", "tcp" and
|
||||||
|
* "unix"
|
||||||
|
* CLIENT *
|
||||||
|
* clnt_create(host, prog, vers, prot)
|
||||||
|
* char *host; -- hostname
|
||||||
|
* unsigned long prog; -- program number
|
||||||
|
* u_ong vers; -- version number
|
||||||
|
* char *prot; -- protocol
|
||||||
|
*/
|
||||||
|
extern CLIENT *clnt_create (const char *__host, const unsigned long __prog,
|
||||||
|
const unsigned long __vers, const char *__prot)
|
||||||
|
;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UDP based rpc.
|
||||||
|
* CLIENT *
|
||||||
|
* clntudp_create(raddr, program, version, wait, sockp)
|
||||||
|
* struct sockaddr_in *raddr;
|
||||||
|
* unsigned long program;
|
||||||
|
* unsigned long version;
|
||||||
|
* struct timeval wait_resend;
|
||||||
|
* int *sockp;
|
||||||
|
*
|
||||||
|
* Same as above, but you specify max packet sizes.
|
||||||
|
* CLIENT *
|
||||||
|
* clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
|
||||||
|
* struct sockaddr_in *raddr;
|
||||||
|
* unsigned long program;
|
||||||
|
* unsigned long version;
|
||||||
|
* struct timeval wait_resend;
|
||||||
|
* int *sockp;
|
||||||
|
* unsigned int sendsz;
|
||||||
|
* unsigned int recvsz;
|
||||||
|
*/
|
||||||
|
extern CLIENT *clntudp_create (struct sockaddr_in *__raddr, unsigned long __program,
|
||||||
|
unsigned long __version, struct timeval __wait_resend,
|
||||||
|
int *__sockp);
|
||||||
|
extern CLIENT *clntudp_bufcreate (struct sockaddr_in *__raddr,
|
||||||
|
unsigned long __program, unsigned long __version,
|
||||||
|
struct timeval __wait_resend, int *__sockp,
|
||||||
|
unsigned int __sendsz, unsigned int __recvsz);
|
||||||
|
|
||||||
|
extern int callrpc (const char *__host, const unsigned long __prognum,
|
||||||
|
const unsigned long __versnum, const unsigned long __procnum,
|
||||||
|
const xdrproc_t __inproc, const char *__in,
|
||||||
|
const xdrproc_t __outproc, char *__out);
|
||||||
|
|
||||||
|
#define UDPMSGSIZE 8800 /* rpc imposed limit on udp msg size */
|
||||||
|
#define RPCSMALLMSGSIZE 400 /* a more reasonable packet size */
|
||||||
|
|
||||||
|
void clnt_perror(CLIENT *rpch, const char *s);
|
||||||
|
|
||||||
|
#endif /* rpc/clnt.h */
|
95
components/dfs/dfs_v1/filesystems/nfs/rpc/clnt_generic.c
Normal file
95
components/dfs/dfs_v1/filesystems/nfs/rpc/clnt_generic.c
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
/* @(#)clnt_generic.c 2.2 88/08/01 4.0 RPCSRC */
|
||||||
|
/*
|
||||||
|
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||||
|
* unrestricted use provided that this legend is included on all tape
|
||||||
|
* media and as a part of the software program in whole or part. Users
|
||||||
|
* may copy or modify Sun RPC without charge, but are not authorized
|
||||||
|
* to license or distribute it to anyone else except as part of a product or
|
||||||
|
* program developed by the user.
|
||||||
|
*
|
||||||
|
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||||
|
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||||
|
*
|
||||||
|
* Sun RPC is provided with no support and without any obligation on the
|
||||||
|
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||||
|
* modification or enhancement.
|
||||||
|
*
|
||||||
|
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||||
|
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||||
|
* OR ANY PART THEREOF.
|
||||||
|
*
|
||||||
|
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||||
|
* or profits or other special, indirect and consequential damages, even if
|
||||||
|
* Sun has been advised of the possibility of such damages.
|
||||||
|
*
|
||||||
|
* Sun Microsystems, Inc.
|
||||||
|
* 2550 Garcia Avenue
|
||||||
|
* Mountain View, California 94043
|
||||||
|
*/
|
||||||
|
#if !defined(lint) && defined(SCCSIDS)
|
||||||
|
static char sccsid[] = "@(#)clnt_generic.c 1.4 87/08/11 (C) 1987 SMI";
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Copyright (C) 1987, Sun Microsystems, Inc.
|
||||||
|
*/
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generic client creation: takes (hostname, program-number, protocol) and
|
||||||
|
* returns client handle. Default options are set, which the user can
|
||||||
|
* change using the rpc equivalent of ioctl()'s.
|
||||||
|
*/
|
||||||
|
CLIENT *clnt_create(const char *hostname, const unsigned long prog,
|
||||||
|
const unsigned long vers, const char *proto)
|
||||||
|
{
|
||||||
|
int sock;
|
||||||
|
struct sockaddr_in server;
|
||||||
|
struct addrinfo hint, *res = NULL;
|
||||||
|
struct timeval tv;
|
||||||
|
CLIENT *client;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
memset(&hint, 0, sizeof(hint));
|
||||||
|
ret = getaddrinfo(hostname, NULL, &hint, &res);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
rt_kprintf("getaddrinfo err: %d '%s'\n", ret, hostname);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&server, res->ai_addr, sizeof(struct sockaddr_in));
|
||||||
|
freeaddrinfo(res);
|
||||||
|
|
||||||
|
sock = -1;
|
||||||
|
if (strcmp(proto, "udp") == 0)
|
||||||
|
{
|
||||||
|
tv.tv_sec = 5;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
client = clntudp_create(&server, prog, vers, tv, &sock);
|
||||||
|
if (client == NULL) return NULL;
|
||||||
|
tv.tv_sec = 1;
|
||||||
|
clnt_control(client, CLSET_TIMEOUT, (char *)&tv);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_kprintf("unknow protocol\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (client);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clnt_perror(CLIENT *rpch, const char *s)
|
||||||
|
{
|
||||||
|
rt_kprintf("rpc client error:%s\n", s);
|
||||||
|
}
|
406
components/dfs/dfs_v1/filesystems/nfs/rpc/clnt_udp.c
Normal file
406
components/dfs/dfs_v1/filesystems/nfs/rpc/clnt_udp.c
Normal file
|
@ -0,0 +1,406 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
/* @(#)clnt_udp.c 2.2 88/08/01 4.0 RPCSRC */
|
||||||
|
/*
|
||||||
|
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||||
|
* unrestricted use provided that this legend is included on all tape
|
||||||
|
* media and as a part of the software program in whole or part. Users
|
||||||
|
* may copy or modify Sun RPC without charge, but are not authorized
|
||||||
|
* to license or distribute it to anyone else except as part of a product or
|
||||||
|
* program developed by the user.
|
||||||
|
*
|
||||||
|
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||||
|
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||||
|
*
|
||||||
|
* Sun RPC is provided with no support and without any obligation on the
|
||||||
|
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||||
|
* modification or enhancement.
|
||||||
|
*
|
||||||
|
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||||
|
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||||
|
* OR ANY PART THEREOF.
|
||||||
|
*
|
||||||
|
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||||
|
* or profits or other special, indirect and consequential damages, even if
|
||||||
|
* Sun has been advised of the possibility of such damages.
|
||||||
|
*
|
||||||
|
* Sun Microsystems, Inc.
|
||||||
|
* 2550 Garcia Avenue
|
||||||
|
* Mountain View, California 94043
|
||||||
|
*/
|
||||||
|
#if !defined(lint) && defined(SCCSIDS)
|
||||||
|
static char sccsid[] = "@(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* clnt_udp.c, Implements a UDP/IP based, client side RPC.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UDP bases client side rpc operations
|
||||||
|
*/
|
||||||
|
static enum clnt_stat clntudp_call(register CLIENT *cl, /* client handle */
|
||||||
|
unsigned long proc, /* procedure number */
|
||||||
|
xdrproc_t xargs, /* xdr routine for args */
|
||||||
|
char* argsp, /* pointer to args */
|
||||||
|
xdrproc_t xresults, /* xdr routine for results */
|
||||||
|
char* resultsp, /* pointer to results */
|
||||||
|
struct timeval utimeout);
|
||||||
|
|
||||||
|
static void clntudp_abort(void);
|
||||||
|
static void clntudp_geterr(CLIENT *, struct rpc_err *);
|
||||||
|
static bool_t clntudp_freeres(CLIENT *, xdrproc_t, char*);
|
||||||
|
static bool_t clntudp_control(CLIENT *, int, char *);
|
||||||
|
static void clntudp_destroy(CLIENT *);
|
||||||
|
|
||||||
|
static struct clnt_ops udp_ops =
|
||||||
|
{
|
||||||
|
clntudp_call,
|
||||||
|
clntudp_abort,
|
||||||
|
clntudp_geterr,
|
||||||
|
clntudp_freeres,
|
||||||
|
clntudp_destroy,
|
||||||
|
clntudp_control
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Private data kept per client handle
|
||||||
|
*/
|
||||||
|
struct cu_data
|
||||||
|
{
|
||||||
|
int cu_sock;
|
||||||
|
bool_t cu_closeit;
|
||||||
|
struct sockaddr_in cu_raddr;
|
||||||
|
int cu_rlen;
|
||||||
|
struct timeval cu_wait;
|
||||||
|
struct timeval cu_total;
|
||||||
|
struct rpc_err cu_error;
|
||||||
|
XDR cu_outxdrs;
|
||||||
|
unsigned int cu_xdrpos;
|
||||||
|
unsigned int cu_sendsz;
|
||||||
|
char *cu_outbuf;
|
||||||
|
unsigned int cu_recvsz;
|
||||||
|
char cu_inbuf[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a UDP based client handle.
|
||||||
|
* If *sockp<0, *sockp is set to a newly created UPD socket.
|
||||||
|
* If raddr->sin_port is 0 a binder on the remote machine
|
||||||
|
* is consulted for the correct port number.
|
||||||
|
* NB: It is the clients responsibility to close *sockp.
|
||||||
|
* NB: The rpch->cl_auth is initialized to null authentication.
|
||||||
|
* Caller may wish to set this something more useful.
|
||||||
|
*
|
||||||
|
* wait is the amount of time used between retransmitting a call if
|
||||||
|
* no response has been heard; retransmition occurs until the actual
|
||||||
|
* rpc call times out.
|
||||||
|
*
|
||||||
|
* sendsz and recvsz are the maximum allowable packet sizes that can be
|
||||||
|
* sent and received.
|
||||||
|
*/
|
||||||
|
CLIENT *clntudp_bufcreate(struct sockaddr_in *raddr,
|
||||||
|
unsigned long program,
|
||||||
|
unsigned long version,
|
||||||
|
struct timeval wait,
|
||||||
|
int *sockp,
|
||||||
|
unsigned int sendsz,
|
||||||
|
unsigned int recvsz)
|
||||||
|
{
|
||||||
|
CLIENT *cl;
|
||||||
|
register struct cu_data *cu = NULL;
|
||||||
|
struct rpc_msg call_msg;
|
||||||
|
static int xid_count = 0;
|
||||||
|
|
||||||
|
cl = (CLIENT *) rt_malloc (sizeof(CLIENT));
|
||||||
|
if (cl == NULL)
|
||||||
|
{
|
||||||
|
rt_kprintf("clntudp_create: out of memory\n");
|
||||||
|
goto fooy;
|
||||||
|
}
|
||||||
|
sendsz = ((sendsz + 3) / 4) * 4;
|
||||||
|
recvsz = ((recvsz + 3) / 4) * 4;
|
||||||
|
cu = (struct cu_data *) rt_malloc (sizeof(*cu) + sendsz + recvsz);
|
||||||
|
if (cu == NULL)
|
||||||
|
{
|
||||||
|
rt_kprintf("clntudp_create: out of memory\n");
|
||||||
|
goto fooy;
|
||||||
|
}
|
||||||
|
cu->cu_outbuf = &cu->cu_inbuf[recvsz];
|
||||||
|
|
||||||
|
if (raddr->sin_port == 0) {
|
||||||
|
unsigned short port;
|
||||||
|
extern unsigned short pmap_getport(struct sockaddr_in *address,
|
||||||
|
unsigned long program,
|
||||||
|
unsigned long version,
|
||||||
|
unsigned int protocol);
|
||||||
|
|
||||||
|
if ((port =
|
||||||
|
pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) {
|
||||||
|
rt_kprintf("pmap_getport failure\n");
|
||||||
|
goto fooy;
|
||||||
|
}
|
||||||
|
raddr->sin_port = htons(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
cl->cl_ops = &udp_ops;
|
||||||
|
cl->cl_private = (char*) cu;
|
||||||
|
cu->cu_raddr = *raddr;
|
||||||
|
cu->cu_rlen = sizeof(cu->cu_raddr);
|
||||||
|
cu->cu_wait = wait;
|
||||||
|
cu->cu_total.tv_sec = -1;
|
||||||
|
cu->cu_total.tv_usec = -1;
|
||||||
|
cu->cu_sendsz = sendsz;
|
||||||
|
cu->cu_recvsz = recvsz;
|
||||||
|
call_msg.rm_xid = (uint32_t)(((unsigned long)rt_thread_self()) ^ ((unsigned long)rt_tick_get()) ^ (xid_count++));
|
||||||
|
call_msg.rm_direction = CALL;
|
||||||
|
call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
|
||||||
|
call_msg.rm_call.cb_prog = program;
|
||||||
|
call_msg.rm_call.cb_vers = version;
|
||||||
|
xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf, sendsz, XDR_ENCODE);
|
||||||
|
if (!xdr_callhdr(&(cu->cu_outxdrs), &call_msg))
|
||||||
|
{
|
||||||
|
rt_kprintf("xdr_callhdr failure\n");
|
||||||
|
goto fooy;
|
||||||
|
}
|
||||||
|
cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs));
|
||||||
|
if (*sockp < 0)
|
||||||
|
{
|
||||||
|
*sockp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
if (*sockp < 0)
|
||||||
|
{
|
||||||
|
rt_kprintf("create socket error\n");
|
||||||
|
goto fooy;
|
||||||
|
}
|
||||||
|
cu->cu_closeit = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cu->cu_closeit = FALSE;
|
||||||
|
}
|
||||||
|
cu->cu_sock = *sockp;
|
||||||
|
cl->cl_auth = authnone_create();
|
||||||
|
return (cl);
|
||||||
|
|
||||||
|
fooy:
|
||||||
|
if (cu) rt_free(cu);
|
||||||
|
if (cl) rt_free(cl);
|
||||||
|
|
||||||
|
return ((CLIENT *) NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
CLIENT *clntudp_create(struct sockaddr_in *raddr,
|
||||||
|
unsigned long program,
|
||||||
|
unsigned long version,
|
||||||
|
struct timeval wait,
|
||||||
|
int *sockp)
|
||||||
|
{
|
||||||
|
return (clntudp_bufcreate(raddr, program, version, wait, sockp,
|
||||||
|
UDPMSGSIZE, UDPMSGSIZE));
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum clnt_stat clntudp_call(CLIENT *cl, unsigned long proc,
|
||||||
|
xdrproc_t xargs, char* argsp,
|
||||||
|
xdrproc_t xresults, char* resultsp,
|
||||||
|
struct timeval utimeout)
|
||||||
|
{
|
||||||
|
register struct cu_data *cu = (struct cu_data *) cl->cl_private;
|
||||||
|
register XDR *xdrs;
|
||||||
|
register int outlen;
|
||||||
|
register int inlen;
|
||||||
|
socklen_t fromlen;
|
||||||
|
|
||||||
|
struct sockaddr_in from;
|
||||||
|
struct rpc_msg reply_msg;
|
||||||
|
XDR reply_xdrs;
|
||||||
|
bool_t ok;
|
||||||
|
int nrefreshes = 2; /* number of times to refresh cred */
|
||||||
|
|
||||||
|
call_again:
|
||||||
|
xdrs = &(cu->cu_outxdrs);
|
||||||
|
xdrs->x_op = XDR_ENCODE;
|
||||||
|
XDR_SETPOS(xdrs, cu->cu_xdrpos);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the transaction is the first thing in the out buffer
|
||||||
|
*/
|
||||||
|
(*(unsigned long *) (cu->cu_outbuf))++;
|
||||||
|
|
||||||
|
if ((!XDR_PUTLONG(xdrs, (long *) &proc)) ||
|
||||||
|
(!AUTH_MARSHALL(cl->cl_auth, xdrs)) || (!(*xargs) (xdrs, argsp)))
|
||||||
|
{
|
||||||
|
cu->cu_error.re_status = RPC_CANTENCODEARGS;
|
||||||
|
return RPC_CANTENCODEARGS;
|
||||||
|
}
|
||||||
|
outlen = (int) XDR_GETPOS(xdrs);
|
||||||
|
|
||||||
|
send_again:
|
||||||
|
if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0,
|
||||||
|
(struct sockaddr *) &(cu->cu_raddr), cu->cu_rlen)
|
||||||
|
!= outlen)
|
||||||
|
{
|
||||||
|
cu->cu_error.re_errno = errno;
|
||||||
|
cu->cu_error.re_status = RPC_CANTSEND;
|
||||||
|
|
||||||
|
return RPC_CANTSEND;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sub-optimal code appears here because we have
|
||||||
|
* some clock time to spare while the packets are in flight.
|
||||||
|
* (We assume that this is actually only executed once.)
|
||||||
|
*/
|
||||||
|
reply_msg.acpted_rply.ar_verf = _null_auth;
|
||||||
|
reply_msg.acpted_rply.ar_results.where = resultsp;
|
||||||
|
reply_msg.acpted_rply.ar_results.proc = xresults;
|
||||||
|
|
||||||
|
/* do recv */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
fromlen = sizeof(struct sockaddr);
|
||||||
|
|
||||||
|
inlen = recvfrom(cu->cu_sock, cu->cu_inbuf,
|
||||||
|
(int) cu->cu_recvsz, 0,
|
||||||
|
(struct sockaddr *) &from, &fromlen);
|
||||||
|
}while (inlen < 0 && errno == EINTR);
|
||||||
|
|
||||||
|
if (inlen < 4)
|
||||||
|
{
|
||||||
|
rt_kprintf("recv error, len %d\n", inlen);
|
||||||
|
cu->cu_error.re_errno = errno;
|
||||||
|
cu->cu_error.re_status = RPC_CANTRECV;
|
||||||
|
|
||||||
|
return RPC_CANTRECV;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* see if reply transaction id matches sent id */
|
||||||
|
if (*((uint32_t *) (cu->cu_inbuf)) != *((uint32_t *) (cu->cu_outbuf)))
|
||||||
|
goto send_again;
|
||||||
|
|
||||||
|
/* we now assume we have the proper reply */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* now decode and validate the response
|
||||||
|
*/
|
||||||
|
xdrmem_create(&reply_xdrs, cu->cu_inbuf, (unsigned int) inlen, XDR_DECODE);
|
||||||
|
ok = xdr_replymsg(&reply_xdrs, &reply_msg);
|
||||||
|
/* XDR_DESTROY(&reply_xdrs); save a few cycles on noop destroy */
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
_seterr_reply(&reply_msg, &(cu->cu_error));
|
||||||
|
if (cu->cu_error.re_status == RPC_SUCCESS)
|
||||||
|
{
|
||||||
|
if (!AUTH_VALIDATE(cl->cl_auth,
|
||||||
|
&reply_msg.acpted_rply.ar_verf))
|
||||||
|
{
|
||||||
|
cu->cu_error.re_status = RPC_AUTHERROR;
|
||||||
|
cu->cu_error.re_why = AUTH_INVALIDRESP;
|
||||||
|
}
|
||||||
|
if (reply_msg.acpted_rply.ar_verf.oa_base != NULL)
|
||||||
|
{
|
||||||
|
extern bool_t xdr_opaque_auth(XDR *xdrs, struct opaque_auth *ap);
|
||||||
|
|
||||||
|
xdrs->x_op = XDR_FREE;
|
||||||
|
(void) xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf));
|
||||||
|
}
|
||||||
|
} /* end successful completion */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* maybe our credentials need to be refreshed ... */
|
||||||
|
if (nrefreshes > 0 && AUTH_REFRESH(cl->cl_auth))
|
||||||
|
{
|
||||||
|
nrefreshes--;
|
||||||
|
goto call_again;
|
||||||
|
}
|
||||||
|
} /* end of unsuccessful completion */
|
||||||
|
} /* end of valid reply message */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cu->cu_error.re_status = RPC_CANTDECODERES;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (enum clnt_stat)(cu->cu_error.re_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clntudp_geterr(CLIENT *cl, struct rpc_err *errp)
|
||||||
|
{
|
||||||
|
register struct cu_data *cu = (struct cu_data *) cl->cl_private;
|
||||||
|
|
||||||
|
*errp = cu->cu_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t clntudp_freeres(CLIENT *cl, xdrproc_t xdr_res, char* res_ptr)
|
||||||
|
{
|
||||||
|
register struct cu_data *cu = (struct cu_data *) cl->cl_private;
|
||||||
|
register XDR *xdrs = &(cu->cu_outxdrs);
|
||||||
|
|
||||||
|
xdrs->x_op = XDR_FREE;
|
||||||
|
return ((*xdr_res) (xdrs, res_ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clntudp_abort()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t clntudp_control(CLIENT *cl, int request, char *info)
|
||||||
|
{
|
||||||
|
register struct cu_data *cu = (struct cu_data *) cl->cl_private;
|
||||||
|
|
||||||
|
switch (request)
|
||||||
|
{
|
||||||
|
case CLSET_TIMEOUT:
|
||||||
|
{
|
||||||
|
int mtimeout;
|
||||||
|
|
||||||
|
cu->cu_total = *(struct timeval *) info;
|
||||||
|
mtimeout = ((cu->cu_total.tv_sec * 1000) + ((cu->cu_total.tv_usec + 500)/1000));
|
||||||
|
|
||||||
|
/* set socket option, note: lwip only support msecond timeout */
|
||||||
|
setsockopt(cu->cu_sock, SOL_SOCKET, SO_RCVTIMEO,
|
||||||
|
&mtimeout, sizeof(mtimeout));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CLGET_TIMEOUT:
|
||||||
|
*(struct timeval *) info = cu->cu_total;
|
||||||
|
break;
|
||||||
|
case CLSET_RETRY_TIMEOUT:
|
||||||
|
cu->cu_wait = *(struct timeval *) info;
|
||||||
|
break;
|
||||||
|
case CLGET_RETRY_TIMEOUT:
|
||||||
|
*(struct timeval *) info = cu->cu_wait;
|
||||||
|
break;
|
||||||
|
case CLGET_SERVER_ADDR:
|
||||||
|
*(struct sockaddr_in *) info = cu->cu_raddr;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clntudp_destroy(CLIENT *cl)
|
||||||
|
{
|
||||||
|
register struct cu_data *cu = (struct cu_data *) cl->cl_private;
|
||||||
|
|
||||||
|
if (cu->cu_closeit)
|
||||||
|
{
|
||||||
|
lwip_close(cu->cu_sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
XDR_DESTROY(&(cu->cu_outxdrs));
|
||||||
|
rt_free(cu);
|
||||||
|
rt_free(cl);
|
||||||
|
}
|
62
components/dfs/dfs_v1/filesystems/nfs/rpc/pmap.c
Normal file
62
components/dfs/dfs_v1/filesystems/nfs/rpc/pmap.c
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
#include "pmap.h"
|
||||||
|
#include "clnt.h"
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
|
||||||
|
static struct timeval timeout = { 5, 0 };
|
||||||
|
static struct timeval tottimeout = { 60, 0 };
|
||||||
|
|
||||||
|
|
||||||
|
bool_t xdr_pmap(XDR *xdrs, struct pmap *regs)
|
||||||
|
{
|
||||||
|
if (xdr_u_long(xdrs, ®s->pm_prog) &&
|
||||||
|
xdr_u_long(xdrs, ®s->pm_vers) &&
|
||||||
|
xdr_u_long(xdrs, ®s->pm_prot))
|
||||||
|
return (xdr_u_long(xdrs, ®s->pm_port));
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the mapped port for program,version.
|
||||||
|
* Calls the pmap service remotely to do the lookup.
|
||||||
|
* Returns 0 if no map exists.
|
||||||
|
*/
|
||||||
|
unsigned short pmap_getport(struct sockaddr_in *address, unsigned long program, unsigned long version, unsigned int protocol)
|
||||||
|
{
|
||||||
|
unsigned short port = 0;
|
||||||
|
int socket = -1;
|
||||||
|
register CLIENT *client = RT_NULL;
|
||||||
|
struct pmap parms;
|
||||||
|
|
||||||
|
address->sin_port = htons((unsigned short)PMAPPORT);
|
||||||
|
if (protocol == IPPROTO_UDP)
|
||||||
|
client = clntudp_bufcreate(address, PMAPPROG, PMAPVERS, timeout,
|
||||||
|
&socket, RPCSMALLMSGSIZE,
|
||||||
|
RPCSMALLMSGSIZE);
|
||||||
|
|
||||||
|
if (client != (CLIENT *) NULL)
|
||||||
|
{
|
||||||
|
parms.pm_prog = program;
|
||||||
|
parms.pm_vers = version;
|
||||||
|
parms.pm_prot = protocol;
|
||||||
|
parms.pm_port = 0; /* not needed or used */
|
||||||
|
if (CLNT_CALL(client, PMAPPROC_GETPORT, (xdrproc_t)xdr_pmap, (char*)&parms,
|
||||||
|
(xdrproc_t)xdr_u_short, (char*)&port, tottimeout) != RPC_SUCCESS)
|
||||||
|
{
|
||||||
|
rt_kprintf("pmap failure\n");
|
||||||
|
}
|
||||||
|
CLNT_DESTROY(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) lwip_close(socket);
|
||||||
|
address->sin_port = 0;
|
||||||
|
|
||||||
|
return (port);
|
||||||
|
}
|
66
components/dfs/dfs_v1/filesystems/nfs/rpc/pmap.h
Normal file
66
components/dfs/dfs_v1/filesystems/nfs/rpc/pmap.h
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
#ifndef __RPC_PMAP_PROT_H__
|
||||||
|
#define __RPC_PMAP_PROT_H__
|
||||||
|
|
||||||
|
#include <rpc/xdr.h>
|
||||||
|
|
||||||
|
/* The following procedures are supported by the protocol:
|
||||||
|
*
|
||||||
|
* PMAPPROC_NULL() returns ()
|
||||||
|
* takes nothing, returns nothing
|
||||||
|
*
|
||||||
|
* PMAPPROC_SET(struct pmap) returns (bool_t)
|
||||||
|
* TRUE is success, FALSE is failure. Registers the tuple
|
||||||
|
* [prog, vers, prot, port].
|
||||||
|
*
|
||||||
|
* PMAPPROC_UNSET(struct pmap) returns (bool_t)
|
||||||
|
* TRUE is success, FALSE is failure. Un-registers pair
|
||||||
|
* [prog, vers]. prot and port are ignored.
|
||||||
|
*
|
||||||
|
* PMAPPROC_GETPORT(struct pmap) returns (long unsigned).
|
||||||
|
* 0 is failure. Otherwise returns the port number where the pair
|
||||||
|
* [prog, vers] is registered. It may lie!
|
||||||
|
*
|
||||||
|
* PMAPPROC_DUMP() RETURNS (struct pmaplist *)
|
||||||
|
*
|
||||||
|
* PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>)
|
||||||
|
* RETURNS (port, string<>);
|
||||||
|
* usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs);
|
||||||
|
* Calls the procedure on the local machine. If it is not registered,
|
||||||
|
* this procedure is quite; ie it does not return error information!!!
|
||||||
|
* This procedure only is supported on rpc/udp and calls via
|
||||||
|
* rpc/udp. This routine only passes null authentication parameters.
|
||||||
|
* This file has no interface to xdr routines for PMAPPROC_CALLIT.
|
||||||
|
*
|
||||||
|
* The service supports remote procedure calls on udp/ip or tcp/ip socket 111.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PMAPPORT ((unsigned short)111)
|
||||||
|
#define PMAPPROG ((unsigned long)100000)
|
||||||
|
#define PMAPVERS ((unsigned long)2)
|
||||||
|
#define PMAPVERS_PROTO ((unsigned long)2)
|
||||||
|
#define PMAPVERS_ORIG ((unsigned long)1)
|
||||||
|
#define PMAPPROC_NULL ((unsigned long)0)
|
||||||
|
#define PMAPPROC_SET ((unsigned long)1)
|
||||||
|
#define PMAPPROC_UNSET ((unsigned long)2)
|
||||||
|
#define PMAPPROC_GETPORT ((unsigned long)3)
|
||||||
|
#define PMAPPROC_DUMP ((unsigned long)4)
|
||||||
|
#define PMAPPROC_CALLIT ((unsigned long)5)
|
||||||
|
|
||||||
|
struct pmap {
|
||||||
|
long unsigned pm_prog;
|
||||||
|
long unsigned pm_vers;
|
||||||
|
long unsigned pm_prot;
|
||||||
|
long unsigned pm_port;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern bool_t xdr_pmap (XDR *__xdrs, struct pmap *__regs);
|
||||||
|
|
||||||
|
#endif
|
62
components/dfs/dfs_v1/filesystems/nfs/rpc/rpc.h
Normal file
62
components/dfs/dfs_v1/filesystems/nfs/rpc/rpc.h
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
/* @(#)rpc.h 2.3 88/08/10 4.0 RPCSRC; from 1.9 88/02/08 SMI */
|
||||||
|
/*
|
||||||
|
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||||
|
* unrestricted use provided that this legend is included on all tape
|
||||||
|
* media and as a part of the software program in whole or part. Users
|
||||||
|
* may copy or modify Sun RPC without charge, but are not authorized
|
||||||
|
* to license or distribute it to anyone else except as part of a product or
|
||||||
|
* program developed by the user.
|
||||||
|
*
|
||||||
|
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||||
|
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||||
|
*
|
||||||
|
* Sun RPC is provided with no support and without any obligation on the
|
||||||
|
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||||
|
* modification or enhancement.
|
||||||
|
*
|
||||||
|
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||||
|
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||||
|
* OR ANY PART THEREOF.
|
||||||
|
*
|
||||||
|
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||||
|
* or profits or other special, indirect and consequential damages, even if
|
||||||
|
* Sun has been advised of the possibility of such damages.
|
||||||
|
*
|
||||||
|
* Sun Microsystems, Inc.
|
||||||
|
* 2550 Garcia Avenue
|
||||||
|
* Mountain View, California 94043
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rpc.h, Just includes the billions of rpc header files necessary to
|
||||||
|
* do remote procedure calling.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RPC_RPC_H
|
||||||
|
#define _RPC_RPC_H 1
|
||||||
|
|
||||||
|
#include <rpc/types.h> /* some typedefs */
|
||||||
|
|
||||||
|
/* external data representation interfaces */
|
||||||
|
#include <rpc/xdr.h> /* generic (de)serializer */
|
||||||
|
|
||||||
|
#include <rpc/auth.h>
|
||||||
|
|
||||||
|
/* Client side (mostly) remote procedure call */
|
||||||
|
#include <rpc/clnt.h> /* generic rpc stuff */
|
||||||
|
|
||||||
|
/* semi-private protocol headers */
|
||||||
|
#include <rpc/rpc_msg.h> /* protocol for rpc messages */
|
||||||
|
|
||||||
|
#endif
|
203
components/dfs/dfs_v1/filesystems/nfs/rpc/rpc_msg.h
Normal file
203
components/dfs/dfs_v1/filesystems/nfs/rpc/rpc_msg.h
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
/* @(#)rpc_msg.h 2.1 88/07/29 4.0 RPCSRC */
|
||||||
|
/*
|
||||||
|
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||||
|
* unrestricted use provided that this legend is included on all tape
|
||||||
|
* media and as a part of the software program in whole or part. Users
|
||||||
|
* may copy or modify Sun RPC without charge, but are not authorized
|
||||||
|
* to license or distribute it to anyone else except as part of a product or
|
||||||
|
* program developed by the user.
|
||||||
|
*
|
||||||
|
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||||
|
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||||
|
*
|
||||||
|
* Sun RPC is provided with no support and without any obligation on the
|
||||||
|
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||||
|
* modification or enhancement.
|
||||||
|
*
|
||||||
|
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||||
|
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||||
|
* OR ANY PART THEREOF.
|
||||||
|
*
|
||||||
|
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||||
|
* or profits or other special, indirect and consequential damages, even if
|
||||||
|
* Sun has been advised of the possibility of such damages.
|
||||||
|
*
|
||||||
|
* Sun Microsystems, Inc.
|
||||||
|
* 2550 Garcia Avenue
|
||||||
|
* Mountain View, California 94043
|
||||||
|
*/
|
||||||
|
/* @(#)rpc_msg.h 1.7 86/07/16 SMI */
|
||||||
|
|
||||||
|
#ifndef _RPC_MSG_H
|
||||||
|
#define _RPC_MSG_H 1
|
||||||
|
|
||||||
|
#include <rpc/xdr.h>
|
||||||
|
#include <rpc/clnt.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rpc_msg.h
|
||||||
|
* rpc message definition
|
||||||
|
*
|
||||||
|
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define RPC_MSG_VERSION ((unsigned long) 2)
|
||||||
|
#define RPC_SERVICE_PORT ((unsigned short) 2048)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bottom up definition of an rpc message.
|
||||||
|
* NOTE: call and reply use the same overall struct but
|
||||||
|
* different parts of unions within it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum msg_type {
|
||||||
|
CALL=0,
|
||||||
|
REPLY=1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum reply_stat {
|
||||||
|
MSG_ACCEPTED=0,
|
||||||
|
MSG_DENIED=1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum accept_stat {
|
||||||
|
SUCCESS=0,
|
||||||
|
PROG_UNAVAIL=1,
|
||||||
|
PROG_MISMATCH=2,
|
||||||
|
PROC_UNAVAIL=3,
|
||||||
|
GARBAGE_ARGS=4,
|
||||||
|
SYSTEM_ERR=5
|
||||||
|
};
|
||||||
|
|
||||||
|
enum reject_stat {
|
||||||
|
RPC_MISMATCH=0,
|
||||||
|
AUTH_ERROR=1
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reply part of an rpc exchange
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reply to an rpc request that was accepted by the server.
|
||||||
|
* Note: there could be an error even though the request was
|
||||||
|
* accepted.
|
||||||
|
*/
|
||||||
|
struct accepted_reply {
|
||||||
|
struct opaque_auth ar_verf;
|
||||||
|
int ar_stat;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
unsigned long low;
|
||||||
|
unsigned long high;
|
||||||
|
} AR_versions;
|
||||||
|
struct {
|
||||||
|
char* where;
|
||||||
|
xdrproc_t proc;
|
||||||
|
} AR_results;
|
||||||
|
/* and many other null cases */
|
||||||
|
} ru;
|
||||||
|
#define ar_results ru.AR_results
|
||||||
|
#define ar_vers ru.AR_versions
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reply to an rpc request that was rejected by the server.
|
||||||
|
*/
|
||||||
|
struct rejected_reply {
|
||||||
|
int rj_stat;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
unsigned long low;
|
||||||
|
unsigned long high;
|
||||||
|
} RJ_versions;
|
||||||
|
int RJ_why; /* why authentication did not work */
|
||||||
|
} ru;
|
||||||
|
#define rj_vers ru.RJ_versions
|
||||||
|
#define rj_why ru.RJ_why
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Body of a reply to an rpc request.
|
||||||
|
*/
|
||||||
|
struct reply_body {
|
||||||
|
int rp_stat;
|
||||||
|
union {
|
||||||
|
struct accepted_reply RP_ar;
|
||||||
|
struct rejected_reply RP_dr;
|
||||||
|
} ru;
|
||||||
|
#define rp_acpt ru.RP_ar
|
||||||
|
#define rp_rjct ru.RP_dr
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Body of an rpc request call.
|
||||||
|
*/
|
||||||
|
struct call_body {
|
||||||
|
unsigned long cb_rpcvers; /* must be equal to two */
|
||||||
|
unsigned long cb_prog;
|
||||||
|
unsigned long cb_vers;
|
||||||
|
unsigned long cb_proc;
|
||||||
|
struct opaque_auth cb_cred;
|
||||||
|
struct opaque_auth cb_verf; /* protocol specific - provided by client */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The rpc message
|
||||||
|
*/
|
||||||
|
struct rpc_msg {
|
||||||
|
unsigned long rm_xid;
|
||||||
|
int rm_direction;
|
||||||
|
union {
|
||||||
|
struct call_body RM_cmb;
|
||||||
|
struct reply_body RM_rmb;
|
||||||
|
} ru;
|
||||||
|
#define rm_call ru.RM_cmb
|
||||||
|
#define rm_reply ru.RM_rmb
|
||||||
|
};
|
||||||
|
#define acpted_rply ru.RM_rmb.ru.RP_ar
|
||||||
|
#define rjcted_rply ru.RM_rmb.ru.RP_dr
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR routine to handle a rpc message.
|
||||||
|
* xdr_callmsg(xdrs, cmsg)
|
||||||
|
* XDR *xdrs;
|
||||||
|
* struct rpc_msg *cmsg;
|
||||||
|
*/
|
||||||
|
extern bool_t xdr_callmsg (XDR *__xdrs, struct rpc_msg *__cmsg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR routine to pre-serialize the static part of a rpc message.
|
||||||
|
* xdr_callhdr(xdrs, cmsg)
|
||||||
|
* XDR *xdrs;
|
||||||
|
* struct rpc_msg *cmsg;
|
||||||
|
*/
|
||||||
|
extern bool_t xdr_callhdr (XDR *__xdrs, struct rpc_msg *__cmsg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR routine to handle a rpc reply.
|
||||||
|
* xdr_replymsg(xdrs, rmsg)
|
||||||
|
* XDR *xdrs;
|
||||||
|
* struct rpc_msg *rmsg;
|
||||||
|
*/
|
||||||
|
extern bool_t xdr_replymsg (XDR *__xdrs, struct rpc_msg *__rmsg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fills in the error part of a reply message.
|
||||||
|
* _seterr_reply(msg, error)
|
||||||
|
* struct rpc_msg *msg;
|
||||||
|
* struct rpc_err *error;
|
||||||
|
*/
|
||||||
|
extern void _seterr_reply (struct rpc_msg *__msg, struct rpc_err *__error);
|
||||||
|
|
||||||
|
#endif /* rpc/rpc_msg.h */
|
267
components/dfs/dfs_v1/filesystems/nfs/rpc/rpc_prot.c
Normal file
267
components/dfs/dfs_v1/filesystems/nfs/rpc/rpc_prot.c
Normal file
|
@ -0,0 +1,267 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
/* @(#)rpc_prot.c 2.3 88/08/07 4.0 RPCSRC */
|
||||||
|
/*
|
||||||
|
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||||
|
* unrestricted use provided that this legend is included on all tape
|
||||||
|
* media and as a part of the software program in whole or part. Users
|
||||||
|
* may copy or modify Sun RPC without charge, but are not authorized
|
||||||
|
* to license or distribute it to anyone else except as part of a product or
|
||||||
|
* program developed by the user.
|
||||||
|
*
|
||||||
|
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||||
|
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||||
|
*
|
||||||
|
* Sun RPC is provided with no support and without any obligation on the
|
||||||
|
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||||
|
* modification or enhancement.
|
||||||
|
*
|
||||||
|
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||||
|
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||||
|
* OR ANY PART THEREOF.
|
||||||
|
*
|
||||||
|
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||||
|
* or profits or other special, indirect and consequential damages, even if
|
||||||
|
* Sun has been advised of the possibility of such damages.
|
||||||
|
*
|
||||||
|
* Sun Microsystems, Inc.
|
||||||
|
* 2550 Garcia Avenue
|
||||||
|
* Mountain View, California 94043
|
||||||
|
*/
|
||||||
|
#if !defined(lint) && defined(SCCSIDS)
|
||||||
|
static char sccsid[] = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rpc_prot.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||||
|
*
|
||||||
|
* This set of routines implements the rpc message definition,
|
||||||
|
* its serializer and some common rpc utility routines.
|
||||||
|
* The routines are meant for various implementations of rpc -
|
||||||
|
* they are NOT for the rpc client or rpc service implementations!
|
||||||
|
* Because authentication stuff is easy and is part of rpc, the opaque
|
||||||
|
* routines are also in this program.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR an opaque authentication struct
|
||||||
|
* (see auth.h)
|
||||||
|
*/
|
||||||
|
bool_t xdr_opaque_auth(XDR *xdrs, struct opaque_auth *ap)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (xdr_enum(xdrs, &(ap->oa_flavor)))
|
||||||
|
return (xdr_bytes(xdrs, &ap->oa_base,
|
||||||
|
&ap->oa_length, MAX_AUTH_BYTES));
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR a DES block
|
||||||
|
*/
|
||||||
|
bool_t xdr_des_block(XDR *xdrs, des_block *blkp)
|
||||||
|
{
|
||||||
|
return (xdr_opaque(xdrs, (char*) blkp, sizeof(des_block)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR the MSG_ACCEPTED part of a reply message union
|
||||||
|
*/
|
||||||
|
static bool_t xdr_accepted_reply(XDR *xdrs, struct accepted_reply *ar)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* personalized union, rather than calling xdr_union */
|
||||||
|
if (!xdr_opaque_auth(xdrs, &(ar->ar_verf)))
|
||||||
|
return (FALSE);
|
||||||
|
if (!xdr_enum(xdrs, (enum_t *) & (ar->ar_stat)))
|
||||||
|
return (FALSE);
|
||||||
|
switch (ar->ar_stat) {
|
||||||
|
|
||||||
|
case SUCCESS:
|
||||||
|
return ((*(ar->ar_results.proc)) (xdrs, ar->ar_results.where));
|
||||||
|
|
||||||
|
case PROG_MISMATCH:
|
||||||
|
if (!xdr_u_long(xdrs, &(ar->ar_vers.low)))
|
||||||
|
return (FALSE);
|
||||||
|
return (xdr_u_long(xdrs, &(ar->ar_vers.high)));
|
||||||
|
}
|
||||||
|
return (TRUE); /* TRUE => open ended set of problems */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR the MSG_DENIED part of a reply message union
|
||||||
|
*/
|
||||||
|
static bool_t xdr_rejected_reply(XDR *xdrs, struct rejected_reply *rr)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* personalized union, rather than calling xdr_union */
|
||||||
|
if (!xdr_enum(xdrs, (enum_t *) & (rr->rj_stat)))
|
||||||
|
return (FALSE);
|
||||||
|
switch (rr->rj_stat) {
|
||||||
|
|
||||||
|
case RPC_MISMATCH:
|
||||||
|
if (!xdr_u_long(xdrs, &(rr->rj_vers.low)))
|
||||||
|
return (FALSE);
|
||||||
|
return (xdr_u_long(xdrs, &(rr->rj_vers.high)));
|
||||||
|
|
||||||
|
case AUTH_ERROR:
|
||||||
|
return (xdr_enum(xdrs, (enum_t *) & (rr->rj_why)));
|
||||||
|
}
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct xdr_discrim reply_dscrm[3] = {
|
||||||
|
{(int) MSG_ACCEPTED, (xdrproc_t)xdr_accepted_reply},
|
||||||
|
{(int) MSG_DENIED, (xdrproc_t)xdr_rejected_reply},
|
||||||
|
{__dontcare__, NULL_xdrproc_t}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR a reply message
|
||||||
|
*/
|
||||||
|
bool_t xdr_replymsg(XDR *xdrs, struct rpc_msg *rmsg)
|
||||||
|
{
|
||||||
|
if (xdr_u_long(xdrs, &(rmsg->rm_xid)) &&
|
||||||
|
xdr_enum(xdrs, (enum_t *) & (rmsg->rm_direction)) &&
|
||||||
|
(rmsg->rm_direction == REPLY))
|
||||||
|
return (xdr_union(xdrs, (enum_t *) & (rmsg->rm_reply.rp_stat),
|
||||||
|
(char*) & (rmsg->rm_reply.ru), reply_dscrm,
|
||||||
|
NULL_xdrproc_t));
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Serializes the "static part" of a call message header.
|
||||||
|
* The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
|
||||||
|
* The rm_xid is not really static, but the user can easily munge on the fly.
|
||||||
|
*/
|
||||||
|
bool_t xdr_callhdr(XDR *xdrs, struct rpc_msg *cmsg)
|
||||||
|
{
|
||||||
|
|
||||||
|
cmsg->rm_direction = CALL;
|
||||||
|
cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
|
||||||
|
if (
|
||||||
|
(xdrs->x_op == XDR_ENCODE) &&
|
||||||
|
xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
|
||||||
|
xdr_enum(xdrs, (enum_t *) & (cmsg->rm_direction)) &&
|
||||||
|
xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
|
||||||
|
xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)))
|
||||||
|
return (xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)));
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************** Client utility routine ************* */
|
||||||
|
|
||||||
|
static void accepted(enum accept_stat acpt_stat, struct rpc_err *error)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (acpt_stat) {
|
||||||
|
|
||||||
|
case PROG_UNAVAIL:
|
||||||
|
error->re_status = RPC_PROGUNAVAIL;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case PROG_MISMATCH:
|
||||||
|
error->re_status = RPC_PROGVERSMISMATCH;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case PROC_UNAVAIL:
|
||||||
|
error->re_status = RPC_PROCUNAVAIL;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case GARBAGE_ARGS:
|
||||||
|
error->re_status = RPC_CANTDECODEARGS;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case SYSTEM_ERR:
|
||||||
|
error->re_status = RPC_SYSTEMERROR;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case SUCCESS:
|
||||||
|
error->re_status = RPC_SUCCESS;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* something's wrong, but we don't know what ... */
|
||||||
|
error->re_status = RPC_FAILED;
|
||||||
|
error->re_lb.s1 = (long) MSG_ACCEPTED;
|
||||||
|
error->re_lb.s2 = (long) acpt_stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rejected(enum reject_stat rjct_stat, struct rpc_err *error)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (rjct_stat) {
|
||||||
|
|
||||||
|
case RPC_VERSMISMATCH:
|
||||||
|
error->re_status = RPC_VERSMISMATCH;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case AUTH_ERROR:
|
||||||
|
error->re_status = RPC_AUTHERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* something's wrong, but we don't know what ... */
|
||||||
|
error->re_status = RPC_FAILED;
|
||||||
|
error->re_lb.s1 = (long) MSG_DENIED;
|
||||||
|
error->re_lb.s2 = (long) rjct_stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* given a reply message, fills in the error
|
||||||
|
*/
|
||||||
|
void _seterr_reply(struct rpc_msg *msg, struct rpc_err *error)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* optimized for normal, SUCCESSful case */
|
||||||
|
switch (msg->rm_reply.rp_stat) {
|
||||||
|
|
||||||
|
case MSG_ACCEPTED:
|
||||||
|
if (msg->acpted_rply.ar_stat == SUCCESS) {
|
||||||
|
error->re_status = RPC_SUCCESS;
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
accepted((enum accept_stat)msg->acpted_rply.ar_stat, error);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MSG_DENIED:
|
||||||
|
rejected((enum reject_stat)msg->rjcted_rply.rj_stat, error);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
error->re_status = RPC_FAILED;
|
||||||
|
error->re_lb.s1 = (long) (msg->rm_reply.rp_stat);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (error->re_status) {
|
||||||
|
|
||||||
|
case RPC_VERSMISMATCH:
|
||||||
|
error->re_vers.low = msg->rjcted_rply.rj_vers.low;
|
||||||
|
error->re_vers.high = msg->rjcted_rply.rj_vers.high;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RPC_AUTHERROR:
|
||||||
|
error->re_why = msg->rjcted_rply.rj_why;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RPC_PROGVERSMISMATCH:
|
||||||
|
error->re_vers.low = msg->acpted_rply.ar_vers.low;
|
||||||
|
error->re_vers.high = msg->acpted_rply.ar_vers.high;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
89
components/dfs/dfs_v1/filesystems/nfs/rpc/types.h
Normal file
89
components/dfs/dfs_v1/filesystems/nfs/rpc/types.h
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||||
|
* unrestricted use provided that this legend is included on all tape
|
||||||
|
* media and as a part of the software program in whole or part. Users
|
||||||
|
* may copy or modify Sun RPC without charge, but are not authorized
|
||||||
|
* to license or distribute it to anyone else except as part of a product or
|
||||||
|
* program developed by the user.
|
||||||
|
*
|
||||||
|
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||||
|
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||||
|
*
|
||||||
|
* Sun RPC is provided with no support and without any obligation on the
|
||||||
|
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||||
|
* modification or enhancement.
|
||||||
|
*
|
||||||
|
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||||
|
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||||
|
* OR ANY PART THEREOF.
|
||||||
|
*
|
||||||
|
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||||
|
* or profits or other special, indirect and consequential damages, even if
|
||||||
|
* Sun has been advised of the possibility of such damages.
|
||||||
|
*
|
||||||
|
* Sun Microsystems, Inc.
|
||||||
|
* 2550 Garcia Avenue
|
||||||
|
* Mountain View, California 94043
|
||||||
|
*/
|
||||||
|
/* fixincludes should not add extern "C" to this file */
|
||||||
|
/*
|
||||||
|
* Rpc additions to <sys/types.h>
|
||||||
|
*/
|
||||||
|
#ifndef _RPC_TYPES_H
|
||||||
|
#define _RPC_TYPES_H 1
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <lwip/netdb.h>
|
||||||
|
#include <lwip/sockets.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifndef RT_USING_MINILIBC
|
||||||
|
typedef unsigned int u_int;
|
||||||
|
typedef unsigned char u_char;
|
||||||
|
typedef unsigned long u_long;
|
||||||
|
#else
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef int bool_t;
|
||||||
|
typedef int enum_t;
|
||||||
|
|
||||||
|
#if !defined(RT_USING_NEWLIB) && !defined(RT_USING_MUSL)
|
||||||
|
typedef unsigned long dev_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* This needs to be changed to uint32_t in the future */
|
||||||
|
typedef unsigned long rpcprog_t;
|
||||||
|
typedef unsigned long rpcvers_t;
|
||||||
|
typedef unsigned long rpcproc_t;
|
||||||
|
typedef unsigned long rpcprot_t;
|
||||||
|
typedef unsigned long rpcport_t;
|
||||||
|
|
||||||
|
#define __dontcare__ -1
|
||||||
|
|
||||||
|
#ifndef FALSE
|
||||||
|
# define FALSE (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TRUE
|
||||||
|
# define TRUE (1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAXHOSTNAMELEN
|
||||||
|
#define MAXHOSTNAMELEN 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* rpc/types.h */
|
784
components/dfs/dfs_v1/filesystems/nfs/rpc/xdr.c
Normal file
784
components/dfs/dfs_v1/filesystems/nfs/rpc/xdr.c
Normal file
|
@ -0,0 +1,784 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
/* @(#)xdr.c 2.1 88/07/29 4.0 RPCSRC */
|
||||||
|
/*
|
||||||
|
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||||
|
* unrestricted use provided that this legend is included on all tape
|
||||||
|
* media and as a part of the software program in whole or part. Users
|
||||||
|
* may copy or modify Sun RPC without charge, but are not authorized
|
||||||
|
* to license or distribute it to anyone else except as part of a product or
|
||||||
|
* program developed by the user.
|
||||||
|
*
|
||||||
|
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||||
|
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||||
|
*
|
||||||
|
* Sun RPC is provided with no support and without any obligation on the
|
||||||
|
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||||
|
* modification or enhancement.
|
||||||
|
*
|
||||||
|
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||||
|
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||||
|
* OR ANY PART THEREOF.
|
||||||
|
*
|
||||||
|
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||||
|
* or profits or other special, indirect and consequential damages, even if
|
||||||
|
* Sun has been advised of the possibility of such damages.
|
||||||
|
*
|
||||||
|
* Sun Microsystems, Inc.
|
||||||
|
* 2550 Garcia Avenue
|
||||||
|
* Mountain View, California 94043
|
||||||
|
*/
|
||||||
|
#if !defined(lint) && defined(SCCSIDS)
|
||||||
|
static char sccsid[] = "@(#)xdr.c 1.35 87/08/12";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* xdr.c, Generic XDR routines implementation.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1986, Sun Microsystems, Inc.
|
||||||
|
*
|
||||||
|
* These are the "generic" xdr routines used to serialize and de-serialize
|
||||||
|
* most common data items. See xdr.h for more info on the interface to
|
||||||
|
* xdr.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <rpc/types.h>
|
||||||
|
#include <rpc/xdr.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* constants specific to the xdr "protocol"
|
||||||
|
*/
|
||||||
|
#define XDR_FALSE ((long) 0)
|
||||||
|
#define XDR_TRUE ((long) 1)
|
||||||
|
#define LASTUNSIGNED ((unsigned int) 0-1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* for unit alignment
|
||||||
|
*/
|
||||||
|
static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free a data structure using XDR
|
||||||
|
* Not a filter, but a convenient utility nonetheless
|
||||||
|
*/
|
||||||
|
void xdr_free(xdrproc_t proc, char* objp)
|
||||||
|
{
|
||||||
|
XDR x;
|
||||||
|
|
||||||
|
x.x_op = XDR_FREE;
|
||||||
|
(*proc) (&x, objp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR nothing
|
||||||
|
*/
|
||||||
|
bool_t xdr_void( /* xdrs, addr */ )
|
||||||
|
/* XDR *xdrs; */
|
||||||
|
/* char* addr; */
|
||||||
|
{
|
||||||
|
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR integers
|
||||||
|
*/
|
||||||
|
bool_t xdr_int(XDR* xdrs, int* ip)
|
||||||
|
{
|
||||||
|
if (sizeof(int) == sizeof(long)) {
|
||||||
|
return (xdr_long(xdrs, (long *) ip));
|
||||||
|
} else if (sizeof(int) < sizeof(long)) {
|
||||||
|
long l;
|
||||||
|
switch (xdrs->x_op) {
|
||||||
|
case XDR_ENCODE:
|
||||||
|
l = (long) *ip;
|
||||||
|
return XDR_PUTLONG(xdrs, &l);
|
||||||
|
case XDR_DECODE:
|
||||||
|
if (!XDR_GETLONG(xdrs, &l))
|
||||||
|
return FALSE;
|
||||||
|
*ip = (int) l;
|
||||||
|
case XDR_FREE:
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
} else {
|
||||||
|
return (xdr_short(xdrs, (short *) ip));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR unsigned integers
|
||||||
|
*/
|
||||||
|
bool_t xdr_u_int(XDR* xdrs, unsigned int* up)
|
||||||
|
{
|
||||||
|
if (sizeof(unsigned int) == sizeof(unsigned long)) {
|
||||||
|
return (xdr_u_long(xdrs, (unsigned long *) up));
|
||||||
|
} else if (sizeof(unsigned int) < sizeof(unsigned long)) {
|
||||||
|
unsigned long l;
|
||||||
|
switch (xdrs->x_op) {
|
||||||
|
case XDR_ENCODE:
|
||||||
|
l = (unsigned long) *up;
|
||||||
|
return XDR_PUTLONG(xdrs, (long*)&l);
|
||||||
|
case XDR_DECODE:
|
||||||
|
if (!XDR_GETLONG(xdrs, (long*)&l))
|
||||||
|
return FALSE;
|
||||||
|
*up = (unsigned int) l;
|
||||||
|
case XDR_FREE:
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
} else {
|
||||||
|
return (xdr_short(xdrs, (short *) up));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR long integers
|
||||||
|
* same as xdr_u_long - open coded to save a proc call!
|
||||||
|
*/
|
||||||
|
bool_t xdr_long(XDR* xdrs, long* lp)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (xdrs->x_op == XDR_ENCODE
|
||||||
|
&& (sizeof(int32_t) == sizeof(long)
|
||||||
|
|| (int32_t) *lp == *lp))
|
||||||
|
return (XDR_PUTLONG(xdrs, lp));
|
||||||
|
|
||||||
|
if (xdrs->x_op == XDR_DECODE)
|
||||||
|
return (XDR_GETLONG(xdrs, lp));
|
||||||
|
|
||||||
|
if (xdrs->x_op == XDR_FREE)
|
||||||
|
return (TRUE);
|
||||||
|
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR unsigned long integers
|
||||||
|
* same as xdr_long - open coded to save a proc call!
|
||||||
|
*/
|
||||||
|
bool_t xdr_u_long(XDR* xdrs, unsigned long* ulp)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (xdrs->x_op == XDR_DECODE) {
|
||||||
|
long l;
|
||||||
|
if (XDR_GETLONG(xdrs, &l) == FALSE)
|
||||||
|
return FALSE;
|
||||||
|
*ulp = (uint32_t) l;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xdrs->x_op == XDR_ENCODE) {
|
||||||
|
if (sizeof(uint32_t) != sizeof(unsigned long)
|
||||||
|
&& (uint32_t) *ulp != *ulp)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return (XDR_PUTLONG(xdrs, (long *) ulp));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xdrs->x_op == XDR_FREE)
|
||||||
|
return (TRUE);
|
||||||
|
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR long long integers
|
||||||
|
*/
|
||||||
|
bool_t xdr_longlong_t (XDR * xdrs, int64_t* llp)
|
||||||
|
{
|
||||||
|
int32_t t1, t2;
|
||||||
|
|
||||||
|
switch (xdrs->x_op)
|
||||||
|
{
|
||||||
|
case XDR_ENCODE:
|
||||||
|
t1 = (int32_t) ((*llp) >> 32);
|
||||||
|
t2 = (int32_t) (*llp);
|
||||||
|
return (XDR_PUTLONG (xdrs, &t1) && XDR_PUTLONG (xdrs, &t2));
|
||||||
|
|
||||||
|
case XDR_DECODE:
|
||||||
|
if (!XDR_GETLONG (xdrs, &t1) || !XDR_GETLONG (xdrs, &t2))
|
||||||
|
return FALSE;
|
||||||
|
*llp = ((int64_t) t1) << 32;
|
||||||
|
*llp |= (uint32_t) t2;
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
case XDR_FREE:
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR unsigned long long integers
|
||||||
|
*/
|
||||||
|
bool_t xdr_u_longlong_t (XDR * xdrs, uint64_t* ullp)
|
||||||
|
{
|
||||||
|
uint32_t t1, t2;
|
||||||
|
|
||||||
|
switch (xdrs->x_op)
|
||||||
|
{
|
||||||
|
case XDR_ENCODE:
|
||||||
|
t1 = (uint32_t) ((*ullp) >> 32);
|
||||||
|
t2 = (uint32_t) (*ullp);
|
||||||
|
return (XDR_PUTLONG (xdrs, (int32_t *)&t1) &&
|
||||||
|
XDR_PUTLONG (xdrs, (int32_t *)&t2));
|
||||||
|
|
||||||
|
case XDR_DECODE:
|
||||||
|
if (!XDR_GETLONG (xdrs, (int32_t *)&t1) ||
|
||||||
|
!XDR_GETLONG (xdrs, (int32_t *)&t2))
|
||||||
|
return FALSE;
|
||||||
|
*ullp = ((uint64_t) t1) << 32;
|
||||||
|
*ullp |= t2;
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
case XDR_FREE:
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR short integers
|
||||||
|
*/
|
||||||
|
bool_t xdr_short(XDR* xdrs, short* sp)
|
||||||
|
{
|
||||||
|
long l;
|
||||||
|
|
||||||
|
switch (xdrs->x_op) {
|
||||||
|
|
||||||
|
case XDR_ENCODE:
|
||||||
|
l = (long) *sp;
|
||||||
|
return (XDR_PUTLONG(xdrs, &l));
|
||||||
|
|
||||||
|
case XDR_DECODE:
|
||||||
|
if (!XDR_GETLONG(xdrs, &l)) {
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
*sp = (short) l;
|
||||||
|
return (TRUE);
|
||||||
|
|
||||||
|
case XDR_FREE:
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR unsigned short integers
|
||||||
|
*/
|
||||||
|
bool_t xdr_u_short(XDR* xdrs, unsigned short* usp)
|
||||||
|
{
|
||||||
|
unsigned long l;
|
||||||
|
|
||||||
|
switch (xdrs->x_op) {
|
||||||
|
|
||||||
|
case XDR_ENCODE:
|
||||||
|
l = (unsigned long) * usp;
|
||||||
|
return (XDR_PUTLONG(xdrs, (long*)&l));
|
||||||
|
|
||||||
|
case XDR_DECODE:
|
||||||
|
if (!XDR_GETLONG(xdrs, (long*)&l)) {
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
*usp = (unsigned short) l;
|
||||||
|
return (TRUE);
|
||||||
|
|
||||||
|
case XDR_FREE:
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR a char
|
||||||
|
*/
|
||||||
|
bool_t xdr_char(XDR* xdrs, char* cp)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = (*cp);
|
||||||
|
if (!xdr_int(xdrs, &i)) {
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
*cp = i;
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR an unsigned char
|
||||||
|
*/
|
||||||
|
bool_t xdr_u_char(XDR* xdrs, unsigned char* cp)
|
||||||
|
{
|
||||||
|
unsigned int u;
|
||||||
|
|
||||||
|
u = (*cp);
|
||||||
|
if (!xdr_u_int(xdrs, &u)) {
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
*cp = u;
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR booleans
|
||||||
|
*/
|
||||||
|
bool_t xdr_bool(XDR *xdrs, bool_t *bp)
|
||||||
|
{
|
||||||
|
long lb;
|
||||||
|
|
||||||
|
switch (xdrs->x_op) {
|
||||||
|
|
||||||
|
case XDR_ENCODE:
|
||||||
|
lb = *bp ? XDR_TRUE : XDR_FALSE;
|
||||||
|
return (XDR_PUTLONG(xdrs, &lb));
|
||||||
|
|
||||||
|
case XDR_DECODE:
|
||||||
|
if (!XDR_GETLONG(xdrs, &lb)) {
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
*bp = (lb == XDR_FALSE) ? FALSE : TRUE;
|
||||||
|
return (TRUE);
|
||||||
|
|
||||||
|
case XDR_FREE:
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR enumerations
|
||||||
|
*/
|
||||||
|
bool_t xdr_enum(XDR *xdrs, enum_t *ep)
|
||||||
|
{
|
||||||
|
enum sizecheck { SIZEVAL }; /* used to find the size of an enum */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* enums are treated as ints
|
||||||
|
*/
|
||||||
|
/* LINTED */ if (sizeof (enum sizecheck) == sizeof (long)) {
|
||||||
|
return (xdr_long(xdrs, (long *)(void *)ep));
|
||||||
|
} else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (int)) {
|
||||||
|
return (xdr_int(xdrs, (int *)(void *)ep));
|
||||||
|
} else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (short)) {
|
||||||
|
return (xdr_short(xdrs, (short *)(void *)ep));
|
||||||
|
} else {
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR opaque data
|
||||||
|
* Allows the specification of a fixed size sequence of opaque bytes.
|
||||||
|
* cp points to the opaque object and cnt gives the byte length.
|
||||||
|
*/
|
||||||
|
bool_t xdr_opaque(XDR *xdrs, char* cp, unsigned int cnt)
|
||||||
|
{
|
||||||
|
register unsigned int rndup;
|
||||||
|
static char crud[BYTES_PER_XDR_UNIT];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if no data we are done
|
||||||
|
*/
|
||||||
|
if (cnt == 0)
|
||||||
|
return (TRUE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* round byte count to full xdr units
|
||||||
|
*/
|
||||||
|
rndup = cnt % BYTES_PER_XDR_UNIT;
|
||||||
|
if (rndup > 0)
|
||||||
|
rndup = BYTES_PER_XDR_UNIT - rndup;
|
||||||
|
|
||||||
|
if (xdrs->x_op == XDR_DECODE) {
|
||||||
|
if (!XDR_GETBYTES(xdrs, cp, cnt)) {
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
if (rndup == 0)
|
||||||
|
return (TRUE);
|
||||||
|
return (XDR_GETBYTES(xdrs, crud, rndup));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xdrs->x_op == XDR_ENCODE) {
|
||||||
|
if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
if (rndup == 0)
|
||||||
|
return (TRUE);
|
||||||
|
return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xdrs->x_op == XDR_FREE) {
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR counted bytes
|
||||||
|
* *cpp is a pointer to the bytes, *sizep is the count.
|
||||||
|
* If *cpp is NULL maxsize bytes are allocated
|
||||||
|
*/
|
||||||
|
bool_t xdr_bytes(XDR *xdrs, char** cpp, unsigned int *sizep, unsigned int maxsize)
|
||||||
|
{
|
||||||
|
register char *sp = *cpp; /* sp is the actual string pointer */
|
||||||
|
register unsigned int nodesize;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* first deal with the length since xdr bytes are counted
|
||||||
|
*/
|
||||||
|
if (!xdr_u_int(xdrs, sizep)) {
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
nodesize = *sizep;
|
||||||
|
if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* now deal with the actual bytes
|
||||||
|
*/
|
||||||
|
switch (xdrs->x_op) {
|
||||||
|
|
||||||
|
case XDR_DECODE:
|
||||||
|
if (nodesize == 0) {
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
if (sp == NULL) {
|
||||||
|
*cpp = sp = (char *) rt_malloc(nodesize);
|
||||||
|
}
|
||||||
|
if (sp == NULL) {
|
||||||
|
rt_kprintf("xdr_bytes: out of memory\n");
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
/* fall into ... */
|
||||||
|
|
||||||
|
case XDR_ENCODE:
|
||||||
|
return (xdr_opaque(xdrs, sp, nodesize));
|
||||||
|
|
||||||
|
case XDR_FREE:
|
||||||
|
if (sp != NULL) {
|
||||||
|
rt_free(sp);
|
||||||
|
*cpp = NULL;
|
||||||
|
}
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implemented here due to commonality of the object.
|
||||||
|
*/
|
||||||
|
bool_t xdr_netobj(XDR *xdrs, struct netobj *np)
|
||||||
|
{
|
||||||
|
return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR a descriminated union
|
||||||
|
* Support routine for discriminated unions.
|
||||||
|
* You create an array of xdrdiscrim structures, terminated with
|
||||||
|
* an entry with a null procedure pointer. The routine gets
|
||||||
|
* the discriminant value and then searches the array of xdrdiscrims
|
||||||
|
* looking for that value. It calls the procedure given in the xdrdiscrim
|
||||||
|
* to handle the discriminant. If there is no specific routine a default
|
||||||
|
* routine may be called.
|
||||||
|
* If there is no specific or default routine an error is returned.
|
||||||
|
*/
|
||||||
|
bool_t xdr_union(XDR* xdrs, enum_t* dscmp, char* unp, const struct xdr_discrim* choices, xdrproc_t dfault)
|
||||||
|
{
|
||||||
|
register enum_t dscm;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* we deal with the discriminator; it's an enum
|
||||||
|
*/
|
||||||
|
if (!xdr_enum(xdrs, dscmp)) {
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
dscm = *dscmp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* search choices for a value that matches the discriminator.
|
||||||
|
* if we find one, execute the xdr routine for that value.
|
||||||
|
*/
|
||||||
|
for (; choices->proc != NULL_xdrproc_t; choices++) {
|
||||||
|
if (choices->value == dscm)
|
||||||
|
return ((*(choices->proc)) (xdrs, unp, LASTUNSIGNED));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* no match - execute the default xdr routine if there is one
|
||||||
|
*/
|
||||||
|
return ((dfault == NULL_xdrproc_t) ? FALSE :
|
||||||
|
(*dfault) (xdrs, unp, LASTUNSIGNED));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Non-portable xdr primitives.
|
||||||
|
* Care should be taken when moving these routines to new architectures.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR null terminated ASCII strings
|
||||||
|
* xdr_string deals with "C strings" - arrays of bytes that are
|
||||||
|
* terminated by a NULL character. The parameter cpp references a
|
||||||
|
* pointer to storage; If the pointer is null, then the necessary
|
||||||
|
* storage is allocated. The last parameter is the max allowed length
|
||||||
|
* of the string as specified by a protocol.
|
||||||
|
*/
|
||||||
|
bool_t xdr_string(XDR *xdrs, char **cpp, unsigned int maxsize)
|
||||||
|
{
|
||||||
|
register char *sp = *cpp; /* sp is the actual string pointer */
|
||||||
|
unsigned int size;
|
||||||
|
unsigned int nodesize;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* first deal with the length since xdr strings are counted-strings
|
||||||
|
*/
|
||||||
|
switch (xdrs->x_op) {
|
||||||
|
case XDR_FREE:
|
||||||
|
if (sp == NULL) {
|
||||||
|
return (TRUE); /* already free */
|
||||||
|
}
|
||||||
|
/* fall through... */
|
||||||
|
case XDR_ENCODE:
|
||||||
|
size = strlen(sp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!xdr_u_int(xdrs, &size)) {
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
if (size > maxsize) {
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
nodesize = size + 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* now deal with the actual bytes
|
||||||
|
*/
|
||||||
|
switch (xdrs->x_op) {
|
||||||
|
|
||||||
|
case XDR_DECODE:
|
||||||
|
if (nodesize == 0) {
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
if (sp == NULL)
|
||||||
|
*cpp = sp = (char *) rt_malloc(nodesize);
|
||||||
|
if (sp == NULL) {
|
||||||
|
rt_kprintf("xdr_string: out of memory\n");
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
sp[size] = 0;
|
||||||
|
/* fall into ... */
|
||||||
|
|
||||||
|
case XDR_ENCODE:
|
||||||
|
return (xdr_opaque(xdrs, sp, size));
|
||||||
|
|
||||||
|
case XDR_FREE:
|
||||||
|
rt_free(sp);
|
||||||
|
*cpp = NULL;
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wrapper for xdr_string that can be called directly from
|
||||||
|
* routines like clnt_call
|
||||||
|
*/
|
||||||
|
bool_t xdr_wrapstring(XDR *xdrs, char **cpp)
|
||||||
|
{
|
||||||
|
if (xdr_string(xdrs, cpp, LASTUNSIGNED)) {
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR an array of arbitrary elements
|
||||||
|
* *addrp is a pointer to the array, *sizep is the number of elements.
|
||||||
|
* If addrp is NULL (*sizep * elsize) bytes are allocated.
|
||||||
|
* elsize is the size (in bytes) of each element, and elproc is the
|
||||||
|
* xdr procedure to call to handle each element of the array.
|
||||||
|
*/
|
||||||
|
bool_t xdr_array(XDR *xdrs, char **addrp, unsigned int *sizep, unsigned int maxsize, unsigned int elsize, xdrproc_t elproc)
|
||||||
|
{
|
||||||
|
register unsigned int i;
|
||||||
|
register char* target = *addrp;
|
||||||
|
register unsigned int c; /* the actual element count */
|
||||||
|
register bool_t stat = TRUE;
|
||||||
|
register unsigned int nodesize;
|
||||||
|
|
||||||
|
/* like strings, arrays are really counted arrays */
|
||||||
|
if (!xdr_u_int(xdrs, sizep)) {
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
c = *sizep;
|
||||||
|
if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) {
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
/* duh, look for integer overflow (fefe) */
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
nodesize = 0;
|
||||||
|
for (i=c; i; --i) {
|
||||||
|
unsigned int tmp=nodesize+elsize;
|
||||||
|
if (tmp<nodesize) /* overflow */
|
||||||
|
return FALSE;
|
||||||
|
nodesize=tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if we are deserializing, we may need to allocate an array.
|
||||||
|
* We also save time by checking for a null array if we are freeing.
|
||||||
|
*/
|
||||||
|
if (target == NULL)
|
||||||
|
switch (xdrs->x_op) {
|
||||||
|
case XDR_DECODE:
|
||||||
|
if (c == 0)
|
||||||
|
return (TRUE);
|
||||||
|
*addrp = target = rt_malloc(nodesize);
|
||||||
|
if (target == NULL) {
|
||||||
|
rt_kprintf("xdr_array: out of memory\n");
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
memset(target, 0, nodesize);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XDR_FREE:
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* now we xdr each element of array
|
||||||
|
*/
|
||||||
|
for (i = 0; (i < c) && stat; i++) {
|
||||||
|
stat = (*elproc) (xdrs, target, LASTUNSIGNED);
|
||||||
|
target += elsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the array may need freeing
|
||||||
|
*/
|
||||||
|
if (xdrs->x_op == XDR_FREE) {
|
||||||
|
rt_free(*addrp);
|
||||||
|
*addrp = NULL;
|
||||||
|
}
|
||||||
|
return (stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* xdr_vector():
|
||||||
|
*
|
||||||
|
* XDR a fixed length array. Unlike variable-length arrays,
|
||||||
|
* the storage of fixed length arrays is static and unfreeable.
|
||||||
|
* > basep: base of the array
|
||||||
|
* > size: size of the array
|
||||||
|
* > elemsize: size of each element
|
||||||
|
* > xdr_elem: routine to XDR each element
|
||||||
|
*/
|
||||||
|
bool_t xdr_vector(XDR *xdrs, char *basep, unsigned int nelem, unsigned int elemsize, xdrproc_t xdr_elem)
|
||||||
|
{
|
||||||
|
register unsigned int i;
|
||||||
|
register char *elptr;
|
||||||
|
|
||||||
|
elptr = basep;
|
||||||
|
for (i = 0; i < nelem; i++) {
|
||||||
|
if (!(*xdr_elem) (xdrs, elptr, LASTUNSIGNED)) {
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
elptr += elemsize;
|
||||||
|
}
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR an indirect pointer
|
||||||
|
* xdr_reference is for recursively translating a structure that is
|
||||||
|
* referenced by a pointer inside the structure that is currently being
|
||||||
|
* translated. pp references a pointer to storage. If *pp is null
|
||||||
|
* the necessary storage is allocated.
|
||||||
|
* size is the sizeof the referneced structure.
|
||||||
|
* proc is the routine to handle the referenced structure.
|
||||||
|
*/
|
||||||
|
bool_t xdr_reference(XDR *xdrs, char **pp, unsigned int size, xdrproc_t proc)
|
||||||
|
{
|
||||||
|
register char* loc = *pp;
|
||||||
|
register bool_t stat;
|
||||||
|
|
||||||
|
if (loc == NULL)
|
||||||
|
switch (xdrs->x_op) {
|
||||||
|
case XDR_FREE:
|
||||||
|
return (TRUE);
|
||||||
|
|
||||||
|
case XDR_DECODE:
|
||||||
|
*pp = loc = (char*) rt_malloc(size);
|
||||||
|
if (loc == NULL) {
|
||||||
|
rt_kprintf("xdr_reference: out of memory\n");
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
memset(loc, 0, (int) size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
stat = (*proc) (xdrs, loc, LASTUNSIGNED);
|
||||||
|
|
||||||
|
if (xdrs->x_op == XDR_FREE) {
|
||||||
|
rt_free(loc);
|
||||||
|
*pp = NULL;
|
||||||
|
}
|
||||||
|
return (stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* xdr_pointer():
|
||||||
|
*
|
||||||
|
* XDR a pointer to a possibly recursive data structure. This
|
||||||
|
* differs with xdr_reference in that it can serialize/deserialiaze
|
||||||
|
* trees correctly.
|
||||||
|
*
|
||||||
|
* What's sent is actually a union:
|
||||||
|
*
|
||||||
|
* union object_pointer switch (boolean b) {
|
||||||
|
* case TRUE: object_data data;
|
||||||
|
* case FALSE: void nothing;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* > objpp: Pointer to the pointer to the object.
|
||||||
|
* > obj_size: size of the object.
|
||||||
|
* > xdr_obj: routine to XDR an object.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool_t xdr_pointer(XDR *xdrs, char **objpp, unsigned int obj_size, xdrproc_t xdr_obj)
|
||||||
|
{
|
||||||
|
|
||||||
|
bool_t more_data;
|
||||||
|
|
||||||
|
more_data = (*objpp != NULL);
|
||||||
|
if (!xdr_bool(xdrs, &more_data)) {
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
if (!more_data) {
|
||||||
|
*objpp = NULL;
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
return (xdr_reference(xdrs, objpp, obj_size, xdr_obj));
|
||||||
|
}
|
369
components/dfs/dfs_v1/filesystems/nfs/rpc/xdr.h
Normal file
369
components/dfs/dfs_v1/filesystems/nfs/rpc/xdr.h
Normal file
|
@ -0,0 +1,369 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||||
|
* unrestricted use provided that this legend is included on all tape
|
||||||
|
* media and as a part of the software program in whole or part. Users
|
||||||
|
* may copy or modify Sun RPC without charge, but are not authorized
|
||||||
|
* to license or distribute it to anyone else except as part of a product or
|
||||||
|
* program developed by the user.
|
||||||
|
*
|
||||||
|
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||||
|
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||||
|
*
|
||||||
|
* Sun RPC is provided with no support and without any obligation on the
|
||||||
|
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||||
|
* modification or enhancement.
|
||||||
|
*
|
||||||
|
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||||
|
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||||
|
* OR ANY PART THEREOF.
|
||||||
|
*
|
||||||
|
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||||
|
* or profits or other special, indirect and consequential damages, even if
|
||||||
|
* Sun has been advised of the possibility of such damages.
|
||||||
|
*
|
||||||
|
* Sun Microsystems, Inc.
|
||||||
|
* 2550 Garcia Avenue
|
||||||
|
* Mountain View, California 94043
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* xdr.h, External Data Representation Serialization Routines.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RPC_XDR_H
|
||||||
|
#define _RPC_XDR_H
|
||||||
|
|
||||||
|
#include <rpc/types.h>
|
||||||
|
|
||||||
|
/* We need FILE. */
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR provides a conventional way for converting between C data
|
||||||
|
* types and an external bit-string representation. Library supplied
|
||||||
|
* routines provide for the conversion on built-in C data types. These
|
||||||
|
* routines and utility routines defined here are used to help implement
|
||||||
|
* a type encode/decode routine for each user-defined type.
|
||||||
|
*
|
||||||
|
* Each data type provides a single procedure which takes two arguments:
|
||||||
|
*
|
||||||
|
* bool_t
|
||||||
|
* xdrproc(xdrs, argresp)
|
||||||
|
* XDR *xdrs;
|
||||||
|
* <type> *argresp;
|
||||||
|
*
|
||||||
|
* xdrs is an instance of a XDR handle, to which or from which the data
|
||||||
|
* type is to be converted. argresp is a pointer to the structure to be
|
||||||
|
* converted. The XDR handle contains an operation field which indicates
|
||||||
|
* which of the operations (ENCODE, DECODE * or FREE) is to be performed.
|
||||||
|
*
|
||||||
|
* XDR_DECODE may allocate space if the pointer argresp is null. This
|
||||||
|
* data can be freed with the XDR_FREE operation.
|
||||||
|
*
|
||||||
|
* We write only one procedure per data type to make it easy
|
||||||
|
* to keep the encode and decode procedures for a data type consistent.
|
||||||
|
* In many cases the same code performs all operations on a user defined type,
|
||||||
|
* because all the hard work is done in the component type routines.
|
||||||
|
* decode as a series of calls on the nested data types.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Xdr operations. XDR_ENCODE causes the type to be encoded into the
|
||||||
|
* stream. XDR_DECODE causes the type to be extracted from the stream.
|
||||||
|
* XDR_FREE can be used to release the space allocated by an XDR_DECODE
|
||||||
|
* request.
|
||||||
|
*/
|
||||||
|
enum xdr_op {
|
||||||
|
XDR_ENCODE = 0,
|
||||||
|
XDR_DECODE = 1,
|
||||||
|
XDR_FREE = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the number of bytes per unit of external data.
|
||||||
|
*/
|
||||||
|
#define BYTES_PER_XDR_UNIT (4)
|
||||||
|
/*
|
||||||
|
* This only works if the above is a power of 2. But it's defined to be
|
||||||
|
* 4 by the appropriate RFCs. So it will work. And it's normally quicker
|
||||||
|
* than the old routine.
|
||||||
|
*/
|
||||||
|
#define RNDUP(x) (((x) + BYTES_PER_XDR_UNIT - 1) & ~(BYTES_PER_XDR_UNIT - 1))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The XDR handle.
|
||||||
|
* Contains operation which is being applied to the stream,
|
||||||
|
* an operations vector for the particular implementation (e.g. see xdr_mem.c),
|
||||||
|
* and two private fields for the use of the particular implementation.
|
||||||
|
*/
|
||||||
|
typedef struct XDR XDR;
|
||||||
|
struct XDR
|
||||||
|
{
|
||||||
|
enum xdr_op x_op; /* operation; fast additional param */
|
||||||
|
struct xdr_ops
|
||||||
|
{
|
||||||
|
bool_t (*x_getlong) (XDR *__xdrs, long *__lp);
|
||||||
|
/* get a long from underlying stream */
|
||||||
|
bool_t (*x_putlong) (XDR *__xdrs, const long *__lp);
|
||||||
|
/* put a long to " */
|
||||||
|
bool_t (*x_getbytes) (XDR *__xdrs, char* __addr, unsigned int __len);
|
||||||
|
/* get some bytes from " */
|
||||||
|
bool_t (*x_putbytes) (XDR *__xdrs, const char *__addr, unsigned int __len);
|
||||||
|
/* put some bytes to " */
|
||||||
|
unsigned int (*x_getpostn) (const XDR *__xdrs);
|
||||||
|
/* returns bytes off from beginning */
|
||||||
|
bool_t (*x_setpostn) (XDR *__xdrs, unsigned int __pos);
|
||||||
|
/* lets you reposition the stream */
|
||||||
|
int32_t *(*x_inline) (XDR *__xdrs, unsigned int __len);
|
||||||
|
/* buf quick ptr to buffered data */
|
||||||
|
void (*x_destroy) (XDR *__xdrs);
|
||||||
|
/* free privates of this xdr_stream */
|
||||||
|
bool_t (*x_getint32) (XDR *__xdrs, int32_t *__ip);
|
||||||
|
/* get a int from underlying stream */
|
||||||
|
bool_t (*x_putint32) (XDR *__xdrs, const int32_t *__ip);
|
||||||
|
/* put a int to " */
|
||||||
|
}
|
||||||
|
*x_ops;
|
||||||
|
char* x_public; /* users' data */
|
||||||
|
char* x_private; /* pointer to private data */
|
||||||
|
char* x_base; /* private used for position info */
|
||||||
|
unsigned int x_handy; /* extra private word */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A xdrproc_t exists for each data type which is to be encoded or decoded.
|
||||||
|
*
|
||||||
|
* The second argument to the xdrproc_t is a pointer to an opaque pointer.
|
||||||
|
* The opaque pointer generally points to a structure of the data type
|
||||||
|
* to be decoded. If this pointer is 0, then the type routines should
|
||||||
|
* allocate dynamic storage of the appropriate size and return it.
|
||||||
|
* bool_t (*xdrproc_t)(XDR *, char* *);
|
||||||
|
*/
|
||||||
|
typedef bool_t (*xdrproc_t) (XDR *, void *,...);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Operations defined on a XDR handle
|
||||||
|
*
|
||||||
|
* XDR *xdrs;
|
||||||
|
* int32_t *int32p;
|
||||||
|
* long *longp;
|
||||||
|
* char* addr;
|
||||||
|
* unsigned int len;
|
||||||
|
* unsigned int pos;
|
||||||
|
*/
|
||||||
|
#define XDR_GETINT32(xdrs, int32p) \
|
||||||
|
(*(xdrs)->x_ops->x_getint32)(xdrs, int32p)
|
||||||
|
#define xdr_getint32(xdrs, int32p) \
|
||||||
|
(*(xdrs)->x_ops->x_getint32)(xdrs, int32p)
|
||||||
|
|
||||||
|
#define XDR_PUTINT32(xdrs, int32p) \
|
||||||
|
(*(xdrs)->x_ops->x_putint32)(xdrs, int32p)
|
||||||
|
#define xdr_putint32(xdrs, int32p) \
|
||||||
|
(*(xdrs)->x_ops->x_putint32)(xdrs, int32p)
|
||||||
|
|
||||||
|
#define XDR_GETLONG(xdrs, longp) \
|
||||||
|
(*(xdrs)->x_ops->x_getlong)(xdrs, longp)
|
||||||
|
#define xdr_getlong(xdrs, longp) \
|
||||||
|
(*(xdrs)->x_ops->x_getlong)(xdrs, longp)
|
||||||
|
|
||||||
|
#define XDR_PUTLONG(xdrs, longp) \
|
||||||
|
(*(xdrs)->x_ops->x_putlong)(xdrs, longp)
|
||||||
|
#define xdr_putlong(xdrs, longp) \
|
||||||
|
(*(xdrs)->x_ops->x_putlong)(xdrs, longp)
|
||||||
|
|
||||||
|
#define XDR_GETBYTES(xdrs, addr, len) \
|
||||||
|
(*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
|
||||||
|
#define xdr_getbytes(xdrs, addr, len) \
|
||||||
|
(*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
|
||||||
|
|
||||||
|
#define XDR_PUTBYTES(xdrs, addr, len) \
|
||||||
|
(*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
|
||||||
|
#define xdr_putbytes(xdrs, addr, len) \
|
||||||
|
(*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
|
||||||
|
|
||||||
|
#define XDR_GETPOS(xdrs) \
|
||||||
|
(*(xdrs)->x_ops->x_getpostn)(xdrs)
|
||||||
|
#define xdr_getpos(xdrs) \
|
||||||
|
(*(xdrs)->x_ops->x_getpostn)(xdrs)
|
||||||
|
|
||||||
|
#define XDR_SETPOS(xdrs, pos) \
|
||||||
|
(*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
|
||||||
|
#define xdr_setpos(xdrs, pos) \
|
||||||
|
(*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
|
||||||
|
|
||||||
|
#define XDR_INLINE(xdrs, len) \
|
||||||
|
(*(xdrs)->x_ops->x_inline)(xdrs, len)
|
||||||
|
#define xdr_inline(xdrs, len) \
|
||||||
|
(*(xdrs)->x_ops->x_inline)(xdrs, len)
|
||||||
|
|
||||||
|
#define XDR_DESTROY(xdrs) \
|
||||||
|
do { \
|
||||||
|
if ((xdrs)->x_ops->x_destroy) \
|
||||||
|
(*(xdrs)->x_ops->x_destroy)(xdrs); \
|
||||||
|
} while (0)
|
||||||
|
#define xdr_destroy(xdrs) \
|
||||||
|
do { \
|
||||||
|
if ((xdrs)->x_ops->x_destroy) \
|
||||||
|
(*(xdrs)->x_ops->x_destroy)(xdrs); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Support struct for discriminated unions.
|
||||||
|
* You create an array of xdrdiscrim structures, terminated with
|
||||||
|
* a entry with a null procedure pointer. The xdr_union routine gets
|
||||||
|
* the discriminant value and then searches the array of structures
|
||||||
|
* for a matching value. If a match is found the associated xdr routine
|
||||||
|
* is called to handle that part of the union. If there is
|
||||||
|
* no match, then a default routine may be called.
|
||||||
|
* If there is no match and no default routine it is an error.
|
||||||
|
*/
|
||||||
|
#define NULL_xdrproc_t ((xdrproc_t)0)
|
||||||
|
struct xdr_discrim
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
xdrproc_t proc;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Inline routines for fast encode/decode of primitive data types.
|
||||||
|
* Caveat emptor: these use single memory cycles to get the
|
||||||
|
* data from the underlying buffer, and will fail to operate
|
||||||
|
* properly if the data is not aligned. The standard way to use these
|
||||||
|
* is to say:
|
||||||
|
* if ((buf = XDR_INLINE(xdrs, count)) == NULL)
|
||||||
|
* return (FALSE);
|
||||||
|
* <<< macro calls >>>
|
||||||
|
* where ``count'' is the number of bytes of data occupied
|
||||||
|
* by the primitive data types.
|
||||||
|
*
|
||||||
|
* N.B. and frozen for all time: each data type here uses 4 bytes
|
||||||
|
* of external representation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define IXDR_GET_INT32(buf) ((int32_t)ntohl((uint32_t)*(buf)++))
|
||||||
|
#define IXDR_PUT_INT32(buf, v) (*(buf)++ = (int32_t)htonl((uint32_t)(v)))
|
||||||
|
#define IXDR_GET_U_INT32(buf) ((uint32_t)IXDR_GET_INT32(buf))
|
||||||
|
#define IXDR_PUT_U_INT32(buf, v) IXDR_PUT_INT32(buf, (int32_t)(v))
|
||||||
|
|
||||||
|
/* WARNING: The IXDR_*_LONG defines are removed by Sun for new platforms
|
||||||
|
* and shouldn't be used any longer. Code which use this defines or longs
|
||||||
|
* in the RPC code will not work on 64bit Solaris platforms !
|
||||||
|
*/
|
||||||
|
#define IXDR_GET_LONG(buf) ((long)IXDR_GET_U_INT32(buf))
|
||||||
|
#define IXDR_PUT_LONG(buf, v) ((long)IXDR_PUT_INT32(buf, (long)(v)))
|
||||||
|
#define IXDR_GET_U_LONG(buf) ((unsigned long)IXDR_GET_LONG(buf))
|
||||||
|
#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG(buf, (long)(v))
|
||||||
|
|
||||||
|
|
||||||
|
#define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf))
|
||||||
|
#define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf))
|
||||||
|
#define IXDR_GET_SHORT(buf) ((short)IXDR_GET_LONG(buf))
|
||||||
|
#define IXDR_GET_U_SHORT(buf) ((unsigned short)IXDR_GET_LONG(buf))
|
||||||
|
|
||||||
|
#define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG(buf, (long)(v))
|
||||||
|
#define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG(buf, (long)(v))
|
||||||
|
#define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG(buf, (long)(v))
|
||||||
|
#define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG(buf, (long)(v))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are the "generic" xdr routines.
|
||||||
|
* None of these can have const applied because it's not possible to
|
||||||
|
* know whether the call is a read or a write to the passed parameter
|
||||||
|
* also, the XDR structure is always updated by some of these calls.
|
||||||
|
*/
|
||||||
|
extern bool_t xdr_void (void);
|
||||||
|
extern bool_t xdr_short (XDR *__xdrs, short *__sp);
|
||||||
|
extern bool_t xdr_u_short (XDR *__xdrs, unsigned short *__usp);
|
||||||
|
extern bool_t xdr_int (XDR *__xdrs, int *__ip);
|
||||||
|
extern bool_t xdr_u_int (XDR *__xdrs, unsigned int *__up);
|
||||||
|
extern bool_t xdr_long (XDR *__xdrs, long *__lp);
|
||||||
|
extern bool_t xdr_u_long (XDR *__xdrs, unsigned long *__ulp);
|
||||||
|
extern bool_t xdr_hyper (XDR *__xdrs, int64_t *__llp);
|
||||||
|
extern bool_t xdr_u_hyper (XDR *__xdrs, uint64_t *__ullp);
|
||||||
|
extern bool_t xdr_longlong_t (XDR *__xdrs, int64_t *__llp);
|
||||||
|
extern bool_t xdr_u_longlong_t (XDR *__xdrs, uint64_t *__ullp);
|
||||||
|
extern bool_t xdr_int8_t (XDR *__xdrs, int8_t *__ip);
|
||||||
|
extern bool_t xdr_uint8_t (XDR *__xdrs, uint8_t *__up);
|
||||||
|
extern bool_t xdr_int16_t (XDR *__xdrs, int16_t *__ip);
|
||||||
|
extern bool_t xdr_uint16_t (XDR *__xdrs, uint16_t *__up);
|
||||||
|
extern bool_t xdr_int32_t (XDR *__xdrs, int32_t *__ip);
|
||||||
|
extern bool_t xdr_uint32_t (XDR *__xdrs, uint32_t *__up);
|
||||||
|
extern bool_t xdr_int64_t (XDR *__xdrs, int64_t *__ip);
|
||||||
|
extern bool_t xdr_uint64_t (XDR *__xdrs, uint64_t *__up);
|
||||||
|
extern bool_t xdr_bool (XDR *__xdrs, bool_t *__bp);
|
||||||
|
extern bool_t xdr_enum (XDR *__xdrs, enum_t *__ep);
|
||||||
|
extern bool_t xdr_array (XDR * _xdrs, char* *__addrp, unsigned int *__sizep,
|
||||||
|
unsigned int __maxsize, unsigned int __elsize, xdrproc_t __elproc);
|
||||||
|
extern bool_t xdr_bytes (XDR *xdrs, char **cpp, unsigned int *sizep,
|
||||||
|
unsigned int maxsize);
|
||||||
|
extern bool_t xdr_opaque (XDR *__xdrs, char* __cp, unsigned int __cnt);
|
||||||
|
extern bool_t xdr_string (XDR *xdrs, char **cpp, unsigned int maxsize);
|
||||||
|
extern bool_t xdr_union (XDR *__xdrs, enum_t *__dscmp, char *__unp,
|
||||||
|
const struct xdr_discrim *__choices,
|
||||||
|
xdrproc_t dfault);
|
||||||
|
extern bool_t xdr_char (XDR *__xdrs, char *__cp);
|
||||||
|
extern bool_t xdr_u_char (XDR *__xdrs, unsigned char *__cp);
|
||||||
|
extern bool_t xdr_vector (XDR *__xdrs, char *__basep, unsigned int __nelem,
|
||||||
|
unsigned int __elemsize, xdrproc_t __xdr_elem);
|
||||||
|
extern bool_t xdr_float (XDR *__xdrs, float *__fp);
|
||||||
|
extern bool_t xdr_double (XDR *__xdrs, double *__dp);
|
||||||
|
extern bool_t xdr_reference (XDR *__xdrs, char* *__xpp, unsigned int __size,
|
||||||
|
xdrproc_t __proc);
|
||||||
|
extern bool_t xdr_pointer (XDR *__xdrs, char **__objpp,
|
||||||
|
unsigned int __obj_size, xdrproc_t __xdr_obj);
|
||||||
|
extern bool_t xdr_wrapstring (XDR *__xdrs, char **cpp);
|
||||||
|
extern unsigned long xdr_sizeof (xdrproc_t, void *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common opaque bytes objects used by many rpc protocols;
|
||||||
|
* declared here due to commonality.
|
||||||
|
*/
|
||||||
|
#define MAX_NETOBJ_SZ 1024
|
||||||
|
struct netobj
|
||||||
|
{
|
||||||
|
unsigned int n_len;
|
||||||
|
char *n_bytes;
|
||||||
|
};
|
||||||
|
typedef struct netobj netobj;
|
||||||
|
extern bool_t xdr_netobj (XDR *__xdrs, struct netobj *__np);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are the public routines for the various implementations of
|
||||||
|
* xdr streams.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* XDR using memory buffers */
|
||||||
|
extern void xdrmem_create (XDR *__xdrs, const char* __addr,
|
||||||
|
unsigned int __size, enum xdr_op __xop);
|
||||||
|
|
||||||
|
/* XDR pseudo records for tcp */
|
||||||
|
extern void xdrrec_create (XDR *__xdrs, unsigned int __sendsize,
|
||||||
|
unsigned int __recvsize, char* __tcp_handle,
|
||||||
|
int (*__readit) (char *, char *, int),
|
||||||
|
int (*__writeit) (char *, char *, int));
|
||||||
|
|
||||||
|
/* make end of xdr record */
|
||||||
|
extern bool_t xdrrec_endofrecord (XDR *__xdrs, bool_t __sendnow);
|
||||||
|
|
||||||
|
/* move to beginning of next record */
|
||||||
|
extern bool_t xdrrec_skiprecord (XDR *__xdrs);
|
||||||
|
|
||||||
|
/* true if no more input */
|
||||||
|
extern bool_t xdrrec_eof (XDR *__xdrs);
|
||||||
|
|
||||||
|
/* free memory buffers for xdr */
|
||||||
|
extern void xdr_free (xdrproc_t __proc, char *__objp);
|
||||||
|
|
||||||
|
#endif /* rpc/xdr.h */
|
172
components/dfs/dfs_v1/filesystems/nfs/rpc/xdr_mem.c
Normal file
172
components/dfs/dfs_v1/filesystems/nfs/rpc/xdr_mem.c
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
/* @(#)xdr_mem.c 2.1 88/07/29 4.0 RPCSRC */
|
||||||
|
/*
|
||||||
|
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||||
|
* unrestricted use provided that this legend is included on all tape
|
||||||
|
* media and as a part of the software program in whole or part. Users
|
||||||
|
* may copy or modify Sun RPC without charge, but are not authorized
|
||||||
|
* to license or distribute it to anyone else except as part of a product or
|
||||||
|
* program developed by the user.
|
||||||
|
*
|
||||||
|
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||||
|
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||||
|
*
|
||||||
|
* Sun RPC is provided with no support and without any obligation on the
|
||||||
|
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||||
|
* modification or enhancement.
|
||||||
|
*
|
||||||
|
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||||
|
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||||
|
* OR ANY PART THEREOF.
|
||||||
|
*
|
||||||
|
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||||
|
* or profits or other special, indirect and consequential damages, even if
|
||||||
|
* Sun has been advised of the possibility of such damages.
|
||||||
|
*
|
||||||
|
* Sun Microsystems, Inc.
|
||||||
|
* 2550 Garcia Avenue
|
||||||
|
* Mountain View, California 94043
|
||||||
|
*/
|
||||||
|
#if !defined(lint) && defined(SCCSIDS)
|
||||||
|
static char sccsid[] = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* xdr_mem.h, XDR implementation using memory buffers.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||||
|
*
|
||||||
|
* If you have some data to be interpreted as external data representation
|
||||||
|
* or to be converted to external data representation in a memory buffer,
|
||||||
|
* then this is the package for you.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rpc/types.h>
|
||||||
|
#include <rpc/xdr.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
static bool_t xdrmem_getlong (XDR *, long *);
|
||||||
|
static bool_t xdrmem_putlong (XDR *, const long *);
|
||||||
|
static bool_t xdrmem_getbytes (XDR *, char *, unsigned int);
|
||||||
|
static bool_t xdrmem_putbytes (XDR *, const char *, unsigned int);
|
||||||
|
static unsigned int xdrmem_getpos (const XDR *);
|
||||||
|
static bool_t xdrmem_setpos (XDR *, unsigned int);
|
||||||
|
static int32_t *xdrmem_inline (XDR *, unsigned int);
|
||||||
|
static void xdrmem_destroy (XDR *);
|
||||||
|
|
||||||
|
static struct xdr_ops xdrmem_ops = {
|
||||||
|
xdrmem_getlong,
|
||||||
|
xdrmem_putlong,
|
||||||
|
xdrmem_getbytes,
|
||||||
|
xdrmem_putbytes,
|
||||||
|
xdrmem_getpos,
|
||||||
|
xdrmem_setpos,
|
||||||
|
xdrmem_inline,
|
||||||
|
xdrmem_destroy,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The procedure xdrmem_create initializes a stream descriptor for a
|
||||||
|
* memory buffer.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
xdrmem_create (XDR *xdrs, const char* addr, unsigned int size, enum xdr_op op)
|
||||||
|
{
|
||||||
|
xdrs->x_op = op;
|
||||||
|
xdrs->x_ops = &xdrmem_ops;
|
||||||
|
xdrs->x_private = xdrs->x_base = (char*)addr;
|
||||||
|
xdrs->x_handy = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xdrmem_destroy (XDR *xdrs)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t
|
||||||
|
xdrmem_getlong (XDR *xdrs, long *lp)
|
||||||
|
{
|
||||||
|
if (xdrs->x_handy < 4) return FALSE;
|
||||||
|
xdrs->x_handy -= 4;
|
||||||
|
|
||||||
|
*lp = (int32_t) ntohl((*((int32_t *) (xdrs->x_private))));
|
||||||
|
xdrs->x_private += 4;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t
|
||||||
|
xdrmem_putlong (XDR *xdrs, const long *lp)
|
||||||
|
{
|
||||||
|
if (xdrs->x_handy < 4) return FALSE;
|
||||||
|
xdrs->x_handy -= 4;
|
||||||
|
|
||||||
|
*(int32_t *) xdrs->x_private = htonl(*lp);
|
||||||
|
xdrs->x_private += 4;
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t
|
||||||
|
xdrmem_getbytes (XDR *xdrs, char *addr, unsigned int len)
|
||||||
|
{
|
||||||
|
if (xdrs->x_handy < len) return FALSE;
|
||||||
|
xdrs->x_handy -= len;
|
||||||
|
memmove(addr, xdrs->x_private, len);
|
||||||
|
xdrs->x_private += len;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t
|
||||||
|
xdrmem_putbytes (XDR *xdrs, const char *addr, unsigned int len)
|
||||||
|
{
|
||||||
|
if (xdrs->x_handy < len) return FALSE;
|
||||||
|
xdrs->x_handy -= len;
|
||||||
|
memmove(xdrs->x_private, addr, len);
|
||||||
|
xdrs->x_private += len;
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int xdrmem_getpos (const XDR *xdrs)
|
||||||
|
{
|
||||||
|
return ((unsigned long) xdrs->x_private - (unsigned long) xdrs->x_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t xdrmem_setpos(XDR *xdrs, unsigned int pos)
|
||||||
|
{
|
||||||
|
register char* newaddr = xdrs->x_base + pos;
|
||||||
|
register char* lastaddr = xdrs->x_private + xdrs->x_handy;
|
||||||
|
|
||||||
|
if ((long) newaddr > (long) lastaddr
|
||||||
|
|| (UINT_MAX < LONG_MAX
|
||||||
|
&& (long) UINT_MAX < (long) lastaddr - (long) newaddr))
|
||||||
|
return (FALSE);
|
||||||
|
xdrs->x_private = newaddr;
|
||||||
|
xdrs->x_handy = (long) lastaddr - (long) newaddr;
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t *
|
||||||
|
xdrmem_inline (XDR *xdrs, unsigned int len)
|
||||||
|
{
|
||||||
|
int32_t *buf = 0;
|
||||||
|
|
||||||
|
if (xdrs->x_handy >= len) {
|
||||||
|
xdrs->x_handy -= len;
|
||||||
|
buf = (int32_t *) xdrs->x_private;
|
||||||
|
xdrs->x_private += len;
|
||||||
|
}
|
||||||
|
return (buf);
|
||||||
|
}
|
||||||
|
|
9
components/dfs/dfs_v1/filesystems/ramfs/SConscript
Normal file
9
components/dfs/dfs_v1/filesystems/ramfs/SConscript
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
src = Glob('*.c')
|
||||||
|
CPPPATH = [cwd]
|
||||||
|
|
||||||
|
group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS', 'RT_USING_MEMHEAP', 'RT_USING_DFS_RAMFS'], CPPPATH = CPPPATH)
|
||||||
|
|
||||||
|
Return('group')
|
479
components/dfs/dfs_v1/filesystems/ramfs/dfs_ramfs.c
Normal file
479
components/dfs/dfs_v1/filesystems/ramfs/dfs_ramfs.c
Normal file
|
@ -0,0 +1,479 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2013-04-15 Bernard the first version
|
||||||
|
* 2013-05-05 Bernard remove CRC for ramfs persistence
|
||||||
|
* 2013-05-22 Bernard fix the no entry issue.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <dfs.h>
|
||||||
|
#include <dfs_fs.h>
|
||||||
|
#include <dfs_file.h>
|
||||||
|
|
||||||
|
#include "dfs_ramfs.h"
|
||||||
|
|
||||||
|
int dfs_ramfs_mount(struct dfs_filesystem *fs,
|
||||||
|
unsigned long rwflag,
|
||||||
|
const void *data)
|
||||||
|
{
|
||||||
|
struct dfs_ramfs *ramfs;
|
||||||
|
|
||||||
|
if (data == NULL)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
ramfs = (struct dfs_ramfs *)data;
|
||||||
|
fs->data = ramfs;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_ramfs_unmount(struct dfs_filesystem *fs)
|
||||||
|
{
|
||||||
|
fs->data = NULL;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_ramfs_statfs(struct dfs_filesystem *fs, struct statfs *buf)
|
||||||
|
{
|
||||||
|
struct dfs_ramfs *ramfs;
|
||||||
|
|
||||||
|
ramfs = (struct dfs_ramfs *)fs->data;
|
||||||
|
RT_ASSERT(ramfs != NULL);
|
||||||
|
RT_ASSERT(buf != NULL);
|
||||||
|
|
||||||
|
buf->f_bsize = 512;
|
||||||
|
buf->f_blocks = ramfs->memheap.pool_size / 512;
|
||||||
|
buf->f_bfree = ramfs->memheap.available_size / 512;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_ramfs_ioctl(struct dfs_file *file, int cmd, void *args)
|
||||||
|
{
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ramfs_dirent *dfs_ramfs_lookup(struct dfs_ramfs *ramfs,
|
||||||
|
const char *path,
|
||||||
|
rt_size_t *size)
|
||||||
|
{
|
||||||
|
const char *subpath;
|
||||||
|
struct ramfs_dirent *dirent;
|
||||||
|
|
||||||
|
subpath = path;
|
||||||
|
while (*subpath == '/' && *subpath)
|
||||||
|
subpath ++;
|
||||||
|
if (! *subpath) /* is root directory */
|
||||||
|
{
|
||||||
|
*size = 0;
|
||||||
|
|
||||||
|
return &(ramfs->root);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (dirent = rt_list_entry(ramfs->root.list.next, struct ramfs_dirent, list);
|
||||||
|
dirent != &(ramfs->root);
|
||||||
|
dirent = rt_list_entry(dirent->list.next, struct ramfs_dirent, list))
|
||||||
|
{
|
||||||
|
if (rt_strcmp(dirent->name, subpath) == 0)
|
||||||
|
{
|
||||||
|
*size = dirent->size;
|
||||||
|
|
||||||
|
return dirent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* not found */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_ramfs_read(struct dfs_file *file, void *buf, size_t count)
|
||||||
|
{
|
||||||
|
rt_size_t length;
|
||||||
|
struct ramfs_dirent *dirent;
|
||||||
|
|
||||||
|
dirent = (struct ramfs_dirent *)file->vnode->data;
|
||||||
|
RT_ASSERT(dirent != NULL);
|
||||||
|
|
||||||
|
if (count < file->vnode->size - file->pos)
|
||||||
|
length = count;
|
||||||
|
else
|
||||||
|
length = file->vnode->size - file->pos;
|
||||||
|
|
||||||
|
if (length > 0)
|
||||||
|
rt_memcpy(buf, &(dirent->data[file->pos]), length);
|
||||||
|
|
||||||
|
/* update file current position */
|
||||||
|
file->pos += length;
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_ramfs_write(struct dfs_file *fd, const void *buf, size_t count)
|
||||||
|
{
|
||||||
|
struct ramfs_dirent *dirent;
|
||||||
|
struct dfs_ramfs *ramfs;
|
||||||
|
|
||||||
|
dirent = (struct ramfs_dirent *)fd->vnode->data;
|
||||||
|
RT_ASSERT(dirent != NULL);
|
||||||
|
|
||||||
|
ramfs = dirent->fs;
|
||||||
|
RT_ASSERT(ramfs != NULL);
|
||||||
|
|
||||||
|
if (count + fd->pos > fd->vnode->size)
|
||||||
|
{
|
||||||
|
rt_uint8_t *ptr;
|
||||||
|
ptr = rt_memheap_realloc(&(ramfs->memheap), dirent->data, fd->pos + count);
|
||||||
|
if (ptr == NULL)
|
||||||
|
{
|
||||||
|
rt_set_errno(-ENOMEM);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update dirent and file size */
|
||||||
|
dirent->data = ptr;
|
||||||
|
dirent->size = fd->pos + count;
|
||||||
|
fd->vnode->size = dirent->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count > 0)
|
||||||
|
rt_memcpy(dirent->data + fd->pos, buf, count);
|
||||||
|
|
||||||
|
/* update file current position */
|
||||||
|
fd->pos += count;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_ramfs_lseek(struct dfs_file *file, off_t offset)
|
||||||
|
{
|
||||||
|
if (offset <= (off_t)file->vnode->size)
|
||||||
|
{
|
||||||
|
file->pos = offset;
|
||||||
|
|
||||||
|
return file->pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_ramfs_close(struct dfs_file *file)
|
||||||
|
{
|
||||||
|
RT_ASSERT(file->vnode->ref_count > 0);
|
||||||
|
if (file->vnode->ref_count > 1)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
file->vnode->data = NULL;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_ramfs_open(struct dfs_file *file)
|
||||||
|
{
|
||||||
|
rt_size_t size;
|
||||||
|
struct dfs_ramfs *ramfs;
|
||||||
|
struct ramfs_dirent *dirent;
|
||||||
|
struct dfs_filesystem *fs;
|
||||||
|
|
||||||
|
RT_ASSERT(file->vnode->ref_count > 0);
|
||||||
|
if (file->vnode->ref_count > 1)
|
||||||
|
{
|
||||||
|
if (file->vnode->type == FT_DIRECTORY
|
||||||
|
&& !(file->flags & O_DIRECTORY))
|
||||||
|
{
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
file->pos = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs = file->vnode->fs;
|
||||||
|
|
||||||
|
ramfs = (struct dfs_ramfs *)fs->data;
|
||||||
|
RT_ASSERT(ramfs != NULL);
|
||||||
|
|
||||||
|
if (file->flags & O_DIRECTORY)
|
||||||
|
{
|
||||||
|
if (file->flags & O_CREAT)
|
||||||
|
{
|
||||||
|
return -ENOSPC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open directory */
|
||||||
|
dirent = dfs_ramfs_lookup(ramfs, file->vnode->path, &size);
|
||||||
|
if (dirent == NULL)
|
||||||
|
return -ENOENT;
|
||||||
|
if (dirent == &(ramfs->root)) /* it's root directory */
|
||||||
|
{
|
||||||
|
if (!(file->flags & O_DIRECTORY))
|
||||||
|
{
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file->vnode->type = FT_DIRECTORY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dirent = dfs_ramfs_lookup(ramfs, file->vnode->path, &size);
|
||||||
|
if (dirent == &(ramfs->root)) /* it's root directory */
|
||||||
|
{
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dirent == NULL)
|
||||||
|
{
|
||||||
|
if (file->flags & O_CREAT || file->flags & O_WRONLY)
|
||||||
|
{
|
||||||
|
char *name_ptr;
|
||||||
|
|
||||||
|
/* create a file entry */
|
||||||
|
dirent = (struct ramfs_dirent *)
|
||||||
|
rt_memheap_alloc(&(ramfs->memheap),
|
||||||
|
sizeof(struct ramfs_dirent));
|
||||||
|
if (dirent == NULL)
|
||||||
|
{
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove '/' separator */
|
||||||
|
name_ptr = file->vnode->path;
|
||||||
|
while (*name_ptr == '/' && *name_ptr)
|
||||||
|
{
|
||||||
|
name_ptr++;
|
||||||
|
}
|
||||||
|
strncpy(dirent->name, name_ptr, RAMFS_NAME_MAX);
|
||||||
|
|
||||||
|
rt_list_init(&(dirent->list));
|
||||||
|
dirent->data = NULL;
|
||||||
|
dirent->size = 0;
|
||||||
|
dirent->fs = ramfs;
|
||||||
|
file->vnode->type = FT_DIRECTORY;
|
||||||
|
|
||||||
|
/* add to the root directory */
|
||||||
|
rt_list_insert_after(&(ramfs->root.list), &(dirent->list));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Creates a new file.
|
||||||
|
* If the file is existing, it is truncated and overwritten.
|
||||||
|
*/
|
||||||
|
if (file->flags & O_TRUNC)
|
||||||
|
{
|
||||||
|
dirent->size = 0;
|
||||||
|
if (dirent->data != NULL)
|
||||||
|
{
|
||||||
|
rt_memheap_free(dirent->data);
|
||||||
|
dirent->data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file->vnode->data = dirent;
|
||||||
|
file->vnode->size = dirent->size;
|
||||||
|
if (file->flags & O_APPEND)
|
||||||
|
{
|
||||||
|
file->pos = file->vnode->size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file->pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_ramfs_stat(struct dfs_filesystem *fs,
|
||||||
|
const char *path,
|
||||||
|
struct stat *st)
|
||||||
|
{
|
||||||
|
rt_size_t size;
|
||||||
|
struct ramfs_dirent *dirent;
|
||||||
|
struct dfs_ramfs *ramfs;
|
||||||
|
|
||||||
|
ramfs = (struct dfs_ramfs *)fs->data;
|
||||||
|
dirent = dfs_ramfs_lookup(ramfs, path, &size);
|
||||||
|
|
||||||
|
if (dirent == NULL)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
st->st_dev = 0;
|
||||||
|
st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
|
||||||
|
S_IWUSR | S_IWGRP | S_IWOTH;
|
||||||
|
|
||||||
|
st->st_size = dirent->size;
|
||||||
|
st->st_mtime = 0;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_ramfs_getdents(struct dfs_file *file,
|
||||||
|
struct dirent *dirp,
|
||||||
|
uint32_t count)
|
||||||
|
{
|
||||||
|
rt_size_t index, end;
|
||||||
|
struct dirent *d;
|
||||||
|
struct ramfs_dirent *dirent;
|
||||||
|
struct dfs_ramfs *ramfs;
|
||||||
|
|
||||||
|
dirent = (struct ramfs_dirent *)file->vnode->data;
|
||||||
|
|
||||||
|
ramfs = dirent->fs;
|
||||||
|
RT_ASSERT(ramfs != RT_NULL);
|
||||||
|
|
||||||
|
if (dirent != &(ramfs->root))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* make integer count */
|
||||||
|
count = (count / sizeof(struct dirent));
|
||||||
|
if (count == 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
end = file->pos + count;
|
||||||
|
index = 0;
|
||||||
|
count = 0;
|
||||||
|
for (dirent = rt_list_entry(dirent->list.next, struct ramfs_dirent, list);
|
||||||
|
dirent != &(ramfs->root) && index < end;
|
||||||
|
dirent = rt_list_entry(dirent->list.next, struct ramfs_dirent, list))
|
||||||
|
{
|
||||||
|
if (index >= (rt_size_t)file->pos)
|
||||||
|
{
|
||||||
|
d = dirp + count;
|
||||||
|
d->d_type = DT_REG;
|
||||||
|
d->d_namlen = RT_NAME_MAX;
|
||||||
|
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
|
||||||
|
rt_strncpy(d->d_name, dirent->name, RAMFS_NAME_MAX);
|
||||||
|
|
||||||
|
count += 1;
|
||||||
|
file->pos += 1;
|
||||||
|
}
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count * sizeof(struct dirent);
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_ramfs_unlink(struct dfs_filesystem *fs, const char *path)
|
||||||
|
{
|
||||||
|
rt_size_t size;
|
||||||
|
struct dfs_ramfs *ramfs;
|
||||||
|
struct ramfs_dirent *dirent;
|
||||||
|
|
||||||
|
ramfs = (struct dfs_ramfs *)fs->data;
|
||||||
|
RT_ASSERT(ramfs != NULL);
|
||||||
|
|
||||||
|
dirent = dfs_ramfs_lookup(ramfs, path, &size);
|
||||||
|
if (dirent == NULL)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
rt_list_remove(&(dirent->list));
|
||||||
|
if (dirent->data != NULL)
|
||||||
|
rt_memheap_free(dirent->data);
|
||||||
|
rt_memheap_free(dirent);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_ramfs_rename(struct dfs_filesystem *fs,
|
||||||
|
const char *oldpath,
|
||||||
|
const char *newpath)
|
||||||
|
{
|
||||||
|
struct ramfs_dirent *dirent;
|
||||||
|
struct dfs_ramfs *ramfs;
|
||||||
|
rt_size_t size;
|
||||||
|
|
||||||
|
ramfs = (struct dfs_ramfs *)fs->data;
|
||||||
|
RT_ASSERT(ramfs != NULL);
|
||||||
|
|
||||||
|
dirent = dfs_ramfs_lookup(ramfs, newpath, &size);
|
||||||
|
if (dirent != NULL)
|
||||||
|
return -EEXIST;
|
||||||
|
|
||||||
|
dirent = dfs_ramfs_lookup(ramfs, oldpath, &size);
|
||||||
|
if (dirent == NULL)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
strncpy(dirent->name, newpath, RAMFS_NAME_MAX);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dfs_file_ops _ram_fops =
|
||||||
|
{
|
||||||
|
dfs_ramfs_open,
|
||||||
|
dfs_ramfs_close,
|
||||||
|
dfs_ramfs_ioctl,
|
||||||
|
dfs_ramfs_read,
|
||||||
|
dfs_ramfs_write,
|
||||||
|
NULL, /* flush */
|
||||||
|
dfs_ramfs_lseek,
|
||||||
|
dfs_ramfs_getdents,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct dfs_filesystem_ops _ramfs =
|
||||||
|
{
|
||||||
|
"ram",
|
||||||
|
DFS_FS_FLAG_DEFAULT,
|
||||||
|
&_ram_fops,
|
||||||
|
|
||||||
|
dfs_ramfs_mount,
|
||||||
|
dfs_ramfs_unmount,
|
||||||
|
NULL, /* mkfs */
|
||||||
|
dfs_ramfs_statfs,
|
||||||
|
|
||||||
|
dfs_ramfs_unlink,
|
||||||
|
dfs_ramfs_stat,
|
||||||
|
dfs_ramfs_rename,
|
||||||
|
};
|
||||||
|
|
||||||
|
int dfs_ramfs_init(void)
|
||||||
|
{
|
||||||
|
/* register ram file system */
|
||||||
|
dfs_register(&_ramfs);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
INIT_COMPONENT_EXPORT(dfs_ramfs_init);
|
||||||
|
|
||||||
|
struct dfs_ramfs *dfs_ramfs_create(rt_uint8_t *pool, rt_size_t size)
|
||||||
|
{
|
||||||
|
struct dfs_ramfs *ramfs;
|
||||||
|
rt_uint8_t *data_ptr;
|
||||||
|
rt_err_t result;
|
||||||
|
|
||||||
|
size = RT_ALIGN_DOWN(size, RT_ALIGN_SIZE);
|
||||||
|
ramfs = (struct dfs_ramfs *)pool;
|
||||||
|
|
||||||
|
data_ptr = (rt_uint8_t *)(ramfs + 1);
|
||||||
|
size = size - sizeof(struct dfs_ramfs);
|
||||||
|
size = RT_ALIGN_DOWN(size, RT_ALIGN_SIZE);
|
||||||
|
|
||||||
|
result = rt_memheap_init(&ramfs->memheap, "ramfs", data_ptr, size);
|
||||||
|
if (result != RT_EOK)
|
||||||
|
return NULL;
|
||||||
|
/* detach this memheap object from the system */
|
||||||
|
rt_object_detach((rt_object_t) & (ramfs->memheap));
|
||||||
|
|
||||||
|
/* initialize ramfs object */
|
||||||
|
ramfs->magic = RAMFS_MAGIC;
|
||||||
|
ramfs->memheap.parent.type = RT_Object_Class_MemHeap | RT_Object_Class_Static;
|
||||||
|
|
||||||
|
/* initialize root directory */
|
||||||
|
rt_memset(&(ramfs->root), 0x00, sizeof(ramfs->root));
|
||||||
|
rt_list_init(&(ramfs->root.list));
|
||||||
|
ramfs->root.size = 0;
|
||||||
|
strcpy(ramfs->root.name, ".");
|
||||||
|
ramfs->root.fs = ramfs;
|
||||||
|
|
||||||
|
return ramfs;
|
||||||
|
}
|
||||||
|
|
47
components/dfs/dfs_v1/filesystems/ramfs/dfs_ramfs.h
Normal file
47
components/dfs/dfs_v1/filesystems/ramfs/dfs_ramfs.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2013-04-15 Bernard the first version
|
||||||
|
* 2013-05-05 Bernard remove CRC for ramfs persistence
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DFS_RAMFS_H__
|
||||||
|
#define __DFS_RAMFS_H__
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rtservice.h>
|
||||||
|
|
||||||
|
#define RAMFS_NAME_MAX 32
|
||||||
|
#define RAMFS_MAGIC 0x0A0A0A0A
|
||||||
|
|
||||||
|
struct ramfs_dirent
|
||||||
|
{
|
||||||
|
rt_list_t list;
|
||||||
|
struct dfs_ramfs *fs; /* file system ref */
|
||||||
|
|
||||||
|
char name[RAMFS_NAME_MAX]; /* dirent name */
|
||||||
|
rt_uint8_t *data;
|
||||||
|
|
||||||
|
rt_size_t size; /* file size */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DFS ramfs object
|
||||||
|
*/
|
||||||
|
struct dfs_ramfs
|
||||||
|
{
|
||||||
|
rt_uint32_t magic;
|
||||||
|
|
||||||
|
struct rt_memheap memheap;
|
||||||
|
struct ramfs_dirent root;
|
||||||
|
};
|
||||||
|
|
||||||
|
int dfs_ramfs_init(void);
|
||||||
|
struct dfs_ramfs *dfs_ramfs_create(rt_uint8_t *pool, rt_size_t size);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
15
components/dfs/dfs_v1/filesystems/romfs/SConscript
Normal file
15
components/dfs/dfs_v1/filesystems/romfs/SConscript
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# RT-Thread building script for component
|
||||||
|
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
src = Glob('*.c')
|
||||||
|
CPPPATH = [cwd]
|
||||||
|
|
||||||
|
if GetDepend('DFS_ROMFS_ROOT'):
|
||||||
|
# A new ROMFS root has been defined, we should remove the romfs.c
|
||||||
|
SrcRemove(src, ['romfs.c'])
|
||||||
|
|
||||||
|
group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS','RT_USING_DFS_ROMFS'], CPPPATH = CPPPATH)
|
||||||
|
|
||||||
|
Return('group')
|
384
components/dfs/dfs_v1/filesystems/romfs/dfs_romfs.c
Normal file
384
components/dfs/dfs_v1/filesystems/romfs/dfs_romfs.c
Normal file
|
@ -0,0 +1,384 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <dfs.h>
|
||||||
|
#include <dfs_fs.h>
|
||||||
|
#include <dfs_file.h>
|
||||||
|
|
||||||
|
#include "dfs_romfs.h"
|
||||||
|
|
||||||
|
int dfs_romfs_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data)
|
||||||
|
{
|
||||||
|
struct romfs_dirent *root_dirent;
|
||||||
|
|
||||||
|
if (data == NULL)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
root_dirent = (struct romfs_dirent *)data;
|
||||||
|
fs->data = root_dirent;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_romfs_unmount(struct dfs_filesystem *fs)
|
||||||
|
{
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_romfs_ioctl(struct dfs_file *file, int cmd, void *args)
|
||||||
|
{
|
||||||
|
int ret = RT_EOK;
|
||||||
|
struct romfs_dirent *dirent;
|
||||||
|
|
||||||
|
dirent = (struct romfs_dirent *)file->vnode->data;
|
||||||
|
RT_ASSERT(dirent != NULL);
|
||||||
|
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case RT_FIOGETADDR:
|
||||||
|
{
|
||||||
|
*(rt_ubase_t*)args = (rt_ubase_t)dirent->data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RT_FIOFTRUNCATE:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
ret = -RT_EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_inline int check_dirent(struct romfs_dirent *dirent)
|
||||||
|
{
|
||||||
|
if ((dirent->type != ROMFS_DIRENT_FILE && dirent->type != ROMFS_DIRENT_DIR)
|
||||||
|
|| dirent->size == ~0U)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct romfs_dirent *dfs_romfs_lookup(struct romfs_dirent *root_dirent, const char *path, rt_size_t *size)
|
||||||
|
{
|
||||||
|
rt_size_t index, found;
|
||||||
|
const char *subpath, *subpath_end;
|
||||||
|
struct romfs_dirent *dirent;
|
||||||
|
rt_size_t dirent_size;
|
||||||
|
|
||||||
|
/* Check the root_dirent. */
|
||||||
|
if (check_dirent(root_dirent) != 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (path[0] == '/' && path[1] == '\0')
|
||||||
|
{
|
||||||
|
*size = root_dirent->size;
|
||||||
|
return root_dirent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* goto root directory entries */
|
||||||
|
dirent = (struct romfs_dirent *)root_dirent->data;
|
||||||
|
dirent_size = root_dirent->size;
|
||||||
|
|
||||||
|
/* get the end position of this subpath */
|
||||||
|
subpath_end = path;
|
||||||
|
/* skip /// */
|
||||||
|
while (*subpath_end && *subpath_end == '/')
|
||||||
|
subpath_end ++;
|
||||||
|
subpath = subpath_end;
|
||||||
|
while ((*subpath_end != '/') && *subpath_end)
|
||||||
|
subpath_end ++;
|
||||||
|
|
||||||
|
while (dirent != NULL)
|
||||||
|
{
|
||||||
|
found = 0;
|
||||||
|
|
||||||
|
/* search in folder */
|
||||||
|
for (index = 0; index < dirent_size; index ++)
|
||||||
|
{
|
||||||
|
if (check_dirent(&dirent[index]) != 0)
|
||||||
|
return NULL;
|
||||||
|
if (rt_strlen(dirent[index].name) == (rt_size_t)(subpath_end - subpath) &&
|
||||||
|
rt_strncmp(dirent[index].name, subpath, (subpath_end - subpath)) == 0)
|
||||||
|
{
|
||||||
|
dirent_size = dirent[index].size;
|
||||||
|
|
||||||
|
/* skip /// */
|
||||||
|
while (*subpath_end && *subpath_end == '/')
|
||||||
|
subpath_end ++;
|
||||||
|
subpath = subpath_end;
|
||||||
|
while ((*subpath_end != '/') && *subpath_end)
|
||||||
|
subpath_end ++;
|
||||||
|
|
||||||
|
if (!(*subpath))
|
||||||
|
{
|
||||||
|
*size = dirent_size;
|
||||||
|
return &dirent[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dirent[index].type == ROMFS_DIRENT_DIR)
|
||||||
|
{
|
||||||
|
/* enter directory */
|
||||||
|
dirent = (struct romfs_dirent *)dirent[index].data;
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* return file dirent */
|
||||||
|
return &dirent[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
break; /* not found */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* not found */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_romfs_read(struct dfs_file *file, void *buf, size_t count)
|
||||||
|
{
|
||||||
|
rt_size_t length;
|
||||||
|
struct romfs_dirent *dirent;
|
||||||
|
|
||||||
|
dirent = (struct romfs_dirent *)file->vnode->data;
|
||||||
|
RT_ASSERT(dirent != NULL);
|
||||||
|
|
||||||
|
if (check_dirent(dirent) != 0)
|
||||||
|
{
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count < file->vnode->size - file->pos)
|
||||||
|
length = count;
|
||||||
|
else
|
||||||
|
length = file->vnode->size - file->pos;
|
||||||
|
|
||||||
|
if (length > 0)
|
||||||
|
rt_memcpy(buf, &(dirent->data[file->pos]), length);
|
||||||
|
|
||||||
|
/* update file current position */
|
||||||
|
file->pos += length;
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_romfs_lseek(struct dfs_file *file, off_t offset)
|
||||||
|
{
|
||||||
|
if (offset <= file->vnode->size)
|
||||||
|
{
|
||||||
|
file->pos = offset;
|
||||||
|
return file->pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_romfs_close(struct dfs_file *file)
|
||||||
|
{
|
||||||
|
RT_ASSERT(file->vnode->ref_count > 0);
|
||||||
|
if (file->vnode->ref_count > 1)
|
||||||
|
{
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
file->vnode->data = NULL;
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_romfs_open(struct dfs_file *file)
|
||||||
|
{
|
||||||
|
rt_size_t size;
|
||||||
|
struct romfs_dirent *dirent;
|
||||||
|
struct romfs_dirent *root_dirent;
|
||||||
|
struct dfs_filesystem *fs;
|
||||||
|
|
||||||
|
if (file->flags & (O_CREAT | O_WRONLY | O_APPEND | O_TRUNC | O_RDWR))
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
RT_ASSERT(file->vnode->ref_count > 0);
|
||||||
|
if (file->vnode->ref_count > 1)
|
||||||
|
{
|
||||||
|
if (file->vnode->type == FT_DIRECTORY
|
||||||
|
&& !(file->flags & O_DIRECTORY))
|
||||||
|
{
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
file->pos = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs = file->vnode->fs;
|
||||||
|
root_dirent = (struct romfs_dirent *)fs->data;
|
||||||
|
|
||||||
|
if (check_dirent(root_dirent) != 0)
|
||||||
|
{
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file->flags & (O_CREAT | O_WRONLY | O_APPEND | O_TRUNC | O_RDWR))
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dirent = dfs_romfs_lookup(root_dirent, file->vnode->path, &size);
|
||||||
|
if (dirent == NULL)
|
||||||
|
{
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* entry is a directory file type */
|
||||||
|
if (dirent->type == ROMFS_DIRENT_DIR)
|
||||||
|
{
|
||||||
|
if (!(file->flags & O_DIRECTORY))
|
||||||
|
{
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
file->vnode->type = FT_DIRECTORY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* entry is a file, but open it as a directory */
|
||||||
|
if (file->flags & O_DIRECTORY)
|
||||||
|
{
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
file->vnode->type = FT_REGULAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
file->vnode->data = dirent;
|
||||||
|
file->vnode->size = size;
|
||||||
|
file->pos = 0;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_romfs_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
|
||||||
|
{
|
||||||
|
rt_size_t size;
|
||||||
|
struct romfs_dirent *dirent;
|
||||||
|
struct romfs_dirent *root_dirent;
|
||||||
|
|
||||||
|
root_dirent = (struct romfs_dirent *)fs->data;
|
||||||
|
dirent = dfs_romfs_lookup(root_dirent, path, &size);
|
||||||
|
|
||||||
|
if (dirent == NULL)
|
||||||
|
{
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
st->st_dev = 0;
|
||||||
|
st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
|
||||||
|
S_IWUSR | S_IWGRP | S_IWOTH;
|
||||||
|
|
||||||
|
if (dirent->type == ROMFS_DIRENT_DIR)
|
||||||
|
{
|
||||||
|
st->st_mode &= ~S_IFREG;
|
||||||
|
st->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
st->st_size = dirent->size;
|
||||||
|
st->st_mtime = 0;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_romfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count)
|
||||||
|
{
|
||||||
|
rt_size_t index;
|
||||||
|
rt_size_t len;
|
||||||
|
const char *name;
|
||||||
|
struct dirent *d;
|
||||||
|
struct romfs_dirent *dirent, *sub_dirent;
|
||||||
|
|
||||||
|
dirent = (struct romfs_dirent *)file->vnode->data;
|
||||||
|
if (check_dirent(dirent) != 0)
|
||||||
|
{
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
RT_ASSERT(dirent->type == ROMFS_DIRENT_DIR);
|
||||||
|
|
||||||
|
/* enter directory */
|
||||||
|
dirent = (struct romfs_dirent *)dirent->data;
|
||||||
|
|
||||||
|
/* make integer count */
|
||||||
|
count = (count / sizeof(struct dirent));
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
for (index = 0; index < count && file->pos < file->vnode->size; index++)
|
||||||
|
{
|
||||||
|
d = dirp + index;
|
||||||
|
|
||||||
|
sub_dirent = &dirent[file->pos];
|
||||||
|
name = sub_dirent->name;
|
||||||
|
|
||||||
|
/* fill dirent */
|
||||||
|
if (sub_dirent->type == ROMFS_DIRENT_DIR)
|
||||||
|
d->d_type = DT_DIR;
|
||||||
|
else
|
||||||
|
d->d_type = DT_REG;
|
||||||
|
|
||||||
|
len = rt_strlen(name);
|
||||||
|
RT_ASSERT(len <= RT_UINT8_MAX);
|
||||||
|
d->d_namlen = (rt_uint8_t)len;
|
||||||
|
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
|
||||||
|
rt_strncpy(d->d_name, name, DFS_PATH_MAX);
|
||||||
|
|
||||||
|
/* move to next position */
|
||||||
|
++ file->pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
return index * sizeof(struct dirent);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dfs_file_ops _rom_fops =
|
||||||
|
{
|
||||||
|
dfs_romfs_open,
|
||||||
|
dfs_romfs_close,
|
||||||
|
dfs_romfs_ioctl,
|
||||||
|
dfs_romfs_read,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
dfs_romfs_lseek,
|
||||||
|
dfs_romfs_getdents,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
static const struct dfs_filesystem_ops _romfs =
|
||||||
|
{
|
||||||
|
"rom",
|
||||||
|
DFS_FS_FLAG_DEFAULT,
|
||||||
|
&_rom_fops,
|
||||||
|
|
||||||
|
dfs_romfs_mount,
|
||||||
|
dfs_romfs_unmount,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
NULL,
|
||||||
|
dfs_romfs_stat,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
int dfs_romfs_init(void)
|
||||||
|
{
|
||||||
|
/* register rom file system */
|
||||||
|
dfs_register(&_romfs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
INIT_COMPONENT_EXPORT(dfs_romfs_init);
|
||||||
|
|
31
components/dfs/dfs_v1/filesystems/romfs/dfs_romfs.h
Normal file
31
components/dfs/dfs_v1/filesystems/romfs/dfs_romfs.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2019/01/13 Bernard code cleanup
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DFS_ROMFS_H__
|
||||||
|
#define __DFS_ROMFS_H__
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
#define ROMFS_DIRENT_FILE 0x00
|
||||||
|
#define ROMFS_DIRENT_DIR 0x01
|
||||||
|
|
||||||
|
struct romfs_dirent
|
||||||
|
{
|
||||||
|
rt_uint32_t type; /* dirent type */
|
||||||
|
|
||||||
|
const char *name; /* dirent name */
|
||||||
|
const rt_uint8_t *data; /* file date ptr */
|
||||||
|
rt_size_t size; /* file size */
|
||||||
|
};
|
||||||
|
|
||||||
|
int dfs_romfs_init(void);
|
||||||
|
extern const struct romfs_dirent romfs_root;
|
||||||
|
|
||||||
|
#endif
|
38
components/dfs/dfs_v1/filesystems/romfs/romfs.c
Normal file
38
components/dfs/dfs_v1/filesystems/romfs/romfs.c
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <dfs_romfs.h>
|
||||||
|
|
||||||
|
static const unsigned char _dummy_dummy_txt[] =
|
||||||
|
{
|
||||||
|
0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x21, 0x0d, 0x0a,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct romfs_dirent _dummy[] =
|
||||||
|
{
|
||||||
|
{ROMFS_DIRENT_FILE, "dummy.txt", _dummy_dummy_txt, sizeof(_dummy_dummy_txt)},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char _dummy_txt[] =
|
||||||
|
{
|
||||||
|
0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x21, 0x0d, 0x0a,
|
||||||
|
};
|
||||||
|
|
||||||
|
rt_weak const struct romfs_dirent _root_dirent[] =
|
||||||
|
{
|
||||||
|
{ROMFS_DIRENT_DIR, "dummy", (rt_uint8_t *)_dummy, sizeof(_dummy) / sizeof(_dummy[0])},
|
||||||
|
{ROMFS_DIRENT_FILE, "dummy.txt", _dummy_txt, sizeof(_dummy_txt)},
|
||||||
|
};
|
||||||
|
|
||||||
|
rt_weak const struct romfs_dirent romfs_root =
|
||||||
|
{
|
||||||
|
ROMFS_DIRENT_DIR, "/", (rt_uint8_t *)_root_dirent, sizeof(_root_dirent) / sizeof(_root_dirent[0])
|
||||||
|
};
|
||||||
|
|
97
components/dfs/dfs_v1/filesystems/skeleton/skeleton.c
Normal file
97
components/dfs/dfs_v1/filesystems/skeleton/skeleton.c
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <dfs.h>
|
||||||
|
#include <dfs_fs.h>
|
||||||
|
#include <dfs_file.h>
|
||||||
|
|
||||||
|
#include "dfs_skt_fs.h"
|
||||||
|
|
||||||
|
int dfs_skt_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data)
|
||||||
|
{
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_skt_unmount(struct dfs_filesystem *fs)
|
||||||
|
{
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_skt_ioctl(struct dfs_file *file, int cmd, void *args)
|
||||||
|
{
|
||||||
|
return -RT_EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_skt_read(struct dfs_file *file, void *buf, rt_size_t count)
|
||||||
|
{
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_skt_lseek(struct dfs_file *file, rt_off_t offset)
|
||||||
|
{
|
||||||
|
return -RT_EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_skt_close(struct dfs_file *file)
|
||||||
|
{
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_skt_open(struct dfs_file *file)
|
||||||
|
{
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_skt_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
|
||||||
|
{
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_skt_getdents(struct dfs_file *file, struct dirent *dirp, rt_uint32_t count)
|
||||||
|
{
|
||||||
|
return count * sizeof(struct dirent);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dfs_file_ops _skt_fops =
|
||||||
|
{
|
||||||
|
dfs_skt_open,
|
||||||
|
dfs_skt_close,
|
||||||
|
dfs_skt_ioctl,
|
||||||
|
dfs_skt_read,
|
||||||
|
NULL, /* write */
|
||||||
|
NULL, /* flush */
|
||||||
|
dfs_skt_lseek,
|
||||||
|
dfs_skt_getdents,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct dfs_filesystem_ops _skt_fs =
|
||||||
|
{
|
||||||
|
"skt",
|
||||||
|
DFS_FS_FLAG_DEFAULT,
|
||||||
|
&_skt_fops,
|
||||||
|
|
||||||
|
dfs_skt_mount,
|
||||||
|
dfs_skt_unmount,
|
||||||
|
NULL, /* mkfs */
|
||||||
|
NULL, /* statfs */
|
||||||
|
|
||||||
|
NULL, /* unlink */
|
||||||
|
dfs_skt_stat,
|
||||||
|
NULL, /* rename */
|
||||||
|
};
|
||||||
|
|
||||||
|
int dfs_skt_init(void)
|
||||||
|
{
|
||||||
|
/* register rom file system */
|
||||||
|
dfs_register(&_skt_fs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
INIT_COMPONENT_EXPORT(dfs_skt_init);
|
||||||
|
|
17
components/dfs/dfs_v1/filesystems/skeleton/skeleton.h
Normal file
17
components/dfs/dfs_v1/filesystems/skeleton/skeleton.h
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SKELETON_H__
|
||||||
|
#define __SKELETON_H__
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
int dfs_skt_init(void);
|
||||||
|
|
||||||
|
#endif
|
9
components/dfs/dfs_v1/filesystems/tmpfs/SConscript
Normal file
9
components/dfs/dfs_v1/filesystems/tmpfs/SConscript
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
src = Glob('*.c')
|
||||||
|
CPPPATH = [cwd]
|
||||||
|
|
||||||
|
group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS', 'RT_USING_DFS_TMPFS'], CPPPATH = CPPPATH)
|
||||||
|
|
||||||
|
Return('group')
|
657
components/dfs/dfs_v1/filesystems/tmpfs/dfs_tmpfs.c
Normal file
657
components/dfs/dfs_v1/filesystems/tmpfs/dfs_tmpfs.c
Normal file
|
@ -0,0 +1,657 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2022-10-24 flybreak the first version
|
||||||
|
* 2023-02-01 xqyjlj fix cannot open the same file repeatedly in 'w' mode
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <dfs.h>
|
||||||
|
#include <dfs_fs.h>
|
||||||
|
#include <dfs_file.h>
|
||||||
|
|
||||||
|
#ifdef RT_USING_SMART
|
||||||
|
#include <lwp.h>
|
||||||
|
#include <lwp_user_mm.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "dfs_tmpfs.h"
|
||||||
|
|
||||||
|
#define DBG_TAG "tmpfs"
|
||||||
|
#define DBG_LVL DBG_INFO
|
||||||
|
#include <rtdbg.h>
|
||||||
|
|
||||||
|
static int _path_separate(const char *path, char *parent_path, char *file_name)
|
||||||
|
{
|
||||||
|
const char *path_p, *path_q;
|
||||||
|
|
||||||
|
RT_ASSERT(path[0] == '/');
|
||||||
|
|
||||||
|
file_name[0] = '\0';
|
||||||
|
path_p = path_q = &path[1];
|
||||||
|
__next_dir:
|
||||||
|
while (*path_q != '/' && *path_q != '\0')
|
||||||
|
{
|
||||||
|
path_q++;
|
||||||
|
}
|
||||||
|
if (path_q != path_p) /*sub dir*/
|
||||||
|
{
|
||||||
|
if (*path_q != '\0')
|
||||||
|
{
|
||||||
|
path_q++;
|
||||||
|
path_p = path_q;
|
||||||
|
goto __next_dir;
|
||||||
|
}
|
||||||
|
else /* Last level dir */
|
||||||
|
{
|
||||||
|
rt_memcpy(parent_path, path, path_p - path - 1);
|
||||||
|
parent_path[path_p - path - 1] = '\0';
|
||||||
|
rt_memcpy(file_name, path_p, path_q - path_p);
|
||||||
|
file_name[path_q - path_p] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (parent_path[0] == 0)
|
||||||
|
{
|
||||||
|
parent_path[0] = '/';
|
||||||
|
parent_path[1] = '\0';
|
||||||
|
}
|
||||||
|
LOG_D("parent_path: %s", parent_path);
|
||||||
|
LOG_D("file_name: %s", file_name);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _get_subdir(const char *path, char *name)
|
||||||
|
{
|
||||||
|
const char *subpath = path;
|
||||||
|
while (*subpath == '/' && *subpath)
|
||||||
|
subpath ++;
|
||||||
|
while (*subpath != '/' && *subpath)
|
||||||
|
{
|
||||||
|
*name = *subpath;
|
||||||
|
name ++;
|
||||||
|
subpath ++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _free_subdir(struct tmpfs_file *dfile)
|
||||||
|
{
|
||||||
|
struct tmpfs_file *file;
|
||||||
|
rt_list_t *list, *temp_list;
|
||||||
|
struct tmpfs_sb *superblock;
|
||||||
|
|
||||||
|
RT_ASSERT(dfile->type == TMPFS_TYPE_DIR);
|
||||||
|
|
||||||
|
rt_list_for_each_safe(list, temp_list, &dfile->subdirs)
|
||||||
|
{
|
||||||
|
file = rt_list_entry(list, struct tmpfs_file, sibling);
|
||||||
|
if (file->type == TMPFS_TYPE_DIR)
|
||||||
|
{
|
||||||
|
_free_subdir(file);
|
||||||
|
}
|
||||||
|
if (file->data != NULL)
|
||||||
|
{
|
||||||
|
/* TODO: fix for rt-smart */
|
||||||
|
rt_free(file->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
superblock = file->sb;
|
||||||
|
RT_ASSERT(superblock != NULL);
|
||||||
|
|
||||||
|
rt_spin_lock(&superblock->lock);
|
||||||
|
rt_list_remove(&(file->sibling));
|
||||||
|
rt_spin_unlock(&superblock->lock);
|
||||||
|
|
||||||
|
rt_free(file);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_tmpfs_mount(struct dfs_filesystem *fs,
|
||||||
|
unsigned long rwflag,
|
||||||
|
const void *data)
|
||||||
|
{
|
||||||
|
struct tmpfs_sb *superblock;
|
||||||
|
|
||||||
|
superblock = rt_calloc(1, sizeof(struct tmpfs_sb));
|
||||||
|
superblock->df_size = sizeof(struct tmpfs_sb);
|
||||||
|
superblock->magic = TMPFS_MAGIC;
|
||||||
|
rt_list_init(&superblock->sibling);
|
||||||
|
|
||||||
|
superblock->root.name[0] = '/';
|
||||||
|
superblock->root.sb = superblock;
|
||||||
|
superblock->root.type = TMPFS_TYPE_DIR;
|
||||||
|
rt_list_init(&superblock->root.sibling);
|
||||||
|
rt_list_init(&superblock->root.subdirs);
|
||||||
|
|
||||||
|
rt_spin_lock_init(&superblock->lock);
|
||||||
|
|
||||||
|
fs->data = superblock;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_tmpfs_unmount(struct dfs_filesystem *fs)
|
||||||
|
{
|
||||||
|
struct tmpfs_sb *superblock;
|
||||||
|
|
||||||
|
superblock = (struct tmpfs_sb *)fs->data;
|
||||||
|
RT_ASSERT(superblock != NULL);
|
||||||
|
|
||||||
|
_free_subdir(&(superblock->root));
|
||||||
|
rt_free(superblock);
|
||||||
|
|
||||||
|
fs->data = NULL;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_tmpfs_statfs(struct dfs_filesystem *fs, struct statfs *buf)
|
||||||
|
{
|
||||||
|
struct tmpfs_sb *superblock;
|
||||||
|
|
||||||
|
superblock = (struct tmpfs_sb *)fs->data;
|
||||||
|
RT_ASSERT(superblock != NULL);
|
||||||
|
RT_ASSERT(buf != NULL);
|
||||||
|
|
||||||
|
buf->f_bsize = 512;
|
||||||
|
buf->f_blocks = (superblock->df_size + 511) / 512;
|
||||||
|
buf->f_bfree = 1;
|
||||||
|
buf->f_bavail = buf->f_bfree;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_tmpfs_ioctl(struct dfs_file *file, int cmd, void *args)
|
||||||
|
{
|
||||||
|
struct tmpfs_file *d_file;
|
||||||
|
struct tmpfs_sb *superblock;
|
||||||
|
|
||||||
|
d_file = (struct tmpfs_file *)file->vnode->data;
|
||||||
|
RT_ASSERT(d_file != NULL);
|
||||||
|
|
||||||
|
superblock = d_file->sb;
|
||||||
|
RT_ASSERT(superblock != NULL);
|
||||||
|
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
#ifdef RT_USING_SMART
|
||||||
|
case RT_FIOMMAP2:
|
||||||
|
{
|
||||||
|
struct dfs_mmap2_args *mmap2 = (struct dfs_mmap2_args *)args;
|
||||||
|
if (mmap2)
|
||||||
|
{
|
||||||
|
if (mmap2->length > file->vnode->size)
|
||||||
|
{
|
||||||
|
return -RT_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_D("tmpfile mmap ptr:%x , size:%d\n", d_file->data, mmap2->length);
|
||||||
|
mmap2->ret = lwp_map_user_phy(lwp_self(), RT_NULL, d_file->data, mmap2->length, 0);
|
||||||
|
}
|
||||||
|
return RT_EOK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct tmpfs_file *dfs_tmpfs_lookup(struct tmpfs_sb *superblock,
|
||||||
|
const char *path,
|
||||||
|
rt_size_t *size)
|
||||||
|
{
|
||||||
|
const char *subpath, *curpath, *filename = RT_NULL;
|
||||||
|
char subdir_name[TMPFS_NAME_MAX];
|
||||||
|
struct tmpfs_file *file, *curfile;
|
||||||
|
rt_list_t *list;
|
||||||
|
|
||||||
|
subpath = path;
|
||||||
|
while (*subpath == '/' && *subpath)
|
||||||
|
subpath ++;
|
||||||
|
if (! *subpath) /* is root directory */
|
||||||
|
{
|
||||||
|
*size = 0;
|
||||||
|
return &(superblock->root);
|
||||||
|
}
|
||||||
|
|
||||||
|
curpath = subpath;
|
||||||
|
curfile = &superblock->root;
|
||||||
|
|
||||||
|
find_subpath:
|
||||||
|
while (*subpath != '/' && *subpath)
|
||||||
|
subpath ++;
|
||||||
|
|
||||||
|
if (! *subpath) /* is last directory */
|
||||||
|
filename = curpath;
|
||||||
|
else
|
||||||
|
subpath ++; /* skip '/' */
|
||||||
|
|
||||||
|
memset(subdir_name, 0, TMPFS_NAME_MAX);
|
||||||
|
_get_subdir(curpath, subdir_name);
|
||||||
|
|
||||||
|
rt_spin_lock(&superblock->lock);
|
||||||
|
|
||||||
|
rt_list_for_each(list, &curfile->subdirs)
|
||||||
|
{
|
||||||
|
file = rt_list_entry(list, struct tmpfs_file, sibling);
|
||||||
|
if (filename) /* find file */
|
||||||
|
{
|
||||||
|
if (rt_strcmp(file->name, filename) == 0)
|
||||||
|
{
|
||||||
|
*size = file->size;
|
||||||
|
|
||||||
|
rt_spin_unlock(&superblock->lock);
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (rt_strcmp(file->name, subdir_name) == 0)
|
||||||
|
{
|
||||||
|
*size = file->size;
|
||||||
|
curpath = subpath;
|
||||||
|
curfile = file;
|
||||||
|
rt_spin_unlock(&superblock->lock);
|
||||||
|
goto find_subpath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rt_spin_unlock(&superblock->lock);
|
||||||
|
/* not found */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_tmpfs_read(struct dfs_file *file, void *buf, size_t count)
|
||||||
|
{
|
||||||
|
rt_size_t length;
|
||||||
|
struct tmpfs_file *d_file;
|
||||||
|
|
||||||
|
d_file = (struct tmpfs_file *)file->vnode->data;
|
||||||
|
RT_ASSERT(d_file != NULL);
|
||||||
|
|
||||||
|
if (count < file->vnode->size - file->pos)
|
||||||
|
length = count;
|
||||||
|
else
|
||||||
|
length = file->vnode->size - file->pos;
|
||||||
|
|
||||||
|
if (length > 0)
|
||||||
|
memcpy(buf, &(d_file->data[file->pos]), length);
|
||||||
|
|
||||||
|
/* update file current position */
|
||||||
|
file->pos += length;
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int dfs_tmpfs_write(struct dfs_file *fd, const void *buf, size_t count)
|
||||||
|
{
|
||||||
|
struct tmpfs_file *d_file;
|
||||||
|
struct tmpfs_sb *superblock;
|
||||||
|
|
||||||
|
d_file = (struct tmpfs_file *)fd->vnode->data;
|
||||||
|
RT_ASSERT(d_file != NULL);
|
||||||
|
|
||||||
|
superblock = d_file->sb;
|
||||||
|
RT_ASSERT(superblock != NULL);
|
||||||
|
|
||||||
|
if (count + fd->pos > fd->vnode->size)
|
||||||
|
{
|
||||||
|
rt_uint8_t *ptr;
|
||||||
|
ptr = rt_realloc(d_file->data, fd->pos + count);
|
||||||
|
if (ptr == NULL)
|
||||||
|
{
|
||||||
|
rt_set_errno(-ENOMEM);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
superblock->df_size += (fd->pos - d_file->size + count);
|
||||||
|
/* update d_file and file size */
|
||||||
|
d_file->data = ptr;
|
||||||
|
d_file->size = fd->pos + count;
|
||||||
|
fd->vnode->size = d_file->size;
|
||||||
|
LOG_D("tmpfile ptr:%x, size:%d", ptr, d_file->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count > 0)
|
||||||
|
memcpy(d_file->data + fd->pos, buf, count);
|
||||||
|
|
||||||
|
/* update file current position */
|
||||||
|
fd->pos += count;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_tmpfs_lseek(struct dfs_file *file, off_t offset)
|
||||||
|
{
|
||||||
|
if (offset <= (off_t)file->vnode->size)
|
||||||
|
{
|
||||||
|
file->pos = offset;
|
||||||
|
|
||||||
|
return file->pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_tmpfs_close(struct dfs_file *file)
|
||||||
|
{
|
||||||
|
RT_ASSERT(file->vnode->ref_count > 0);
|
||||||
|
if (file->vnode->ref_count > 1)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
file->vnode->data = NULL;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_tmpfs_open(struct dfs_file *file)
|
||||||
|
{
|
||||||
|
rt_size_t size;
|
||||||
|
struct tmpfs_sb *superblock;
|
||||||
|
struct tmpfs_file *d_file, *p_file;
|
||||||
|
struct dfs_filesystem *fs;
|
||||||
|
char parent_path[DFS_PATH_MAX],file_name[TMPFS_NAME_MAX];
|
||||||
|
|
||||||
|
RT_ASSERT(file->vnode->ref_count > 0);
|
||||||
|
if (file->vnode->ref_count > 1)
|
||||||
|
{
|
||||||
|
if (file->vnode->type == FT_DIRECTORY
|
||||||
|
&& !(file->flags & O_DIRECTORY))
|
||||||
|
{
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
file->pos = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs = file->vnode->fs;
|
||||||
|
|
||||||
|
superblock = (struct tmpfs_sb *)fs->data;
|
||||||
|
RT_ASSERT(superblock != NULL);
|
||||||
|
|
||||||
|
/* find file */
|
||||||
|
d_file = dfs_tmpfs_lookup(superblock, file->vnode->path, &size);
|
||||||
|
if (d_file == NULL && !(file->flags & O_CREAT))
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
/* Creates a new file. */
|
||||||
|
if (file->flags & O_CREAT)
|
||||||
|
{
|
||||||
|
if (d_file == NULL)
|
||||||
|
{
|
||||||
|
/* find parent file */
|
||||||
|
_path_separate(file->vnode->path, parent_path, file_name);
|
||||||
|
if (file_name[0] == '\0') /* it's root dir */
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
/* open parent directory */
|
||||||
|
p_file = dfs_tmpfs_lookup(superblock, parent_path, &size);
|
||||||
|
if (p_file == NULL)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
/* create a file entry */
|
||||||
|
d_file = (struct tmpfs_file *)rt_calloc(1, sizeof(struct tmpfs_file));
|
||||||
|
if (d_file == NULL)
|
||||||
|
{
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
superblock->df_size += sizeof(struct tmpfs_file);
|
||||||
|
|
||||||
|
strncpy(d_file->name, file_name, TMPFS_NAME_MAX);
|
||||||
|
|
||||||
|
rt_list_init(&(d_file->subdirs));
|
||||||
|
rt_list_init(&(d_file->sibling));
|
||||||
|
d_file->data = NULL;
|
||||||
|
d_file->size = 0;
|
||||||
|
d_file->sb = superblock;
|
||||||
|
if (file->flags & O_DIRECTORY)
|
||||||
|
{
|
||||||
|
d_file->type = TMPFS_TYPE_DIR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d_file->type = TMPFS_TYPE_FILE;
|
||||||
|
}
|
||||||
|
rt_spin_lock(&superblock->lock);
|
||||||
|
rt_list_insert_after(&(p_file->subdirs), &(d_file->sibling));
|
||||||
|
rt_spin_unlock(&superblock->lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Creates a new file.
|
||||||
|
* If the file is existing, it is truncated and overwritten.
|
||||||
|
*/
|
||||||
|
if (file->flags & O_TRUNC)
|
||||||
|
{
|
||||||
|
d_file->size = 0;
|
||||||
|
if (d_file->data != NULL)
|
||||||
|
{
|
||||||
|
/* ToDo: fix for rt-smart. */
|
||||||
|
rt_free(d_file->data);
|
||||||
|
d_file->data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fill file */
|
||||||
|
if (d_file->type == TMPFS_TYPE_DIR)
|
||||||
|
{
|
||||||
|
if (file->flags & O_DIRECTORY)
|
||||||
|
file->vnode->type = FT_DIRECTORY;
|
||||||
|
else
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (file->flags & O_DIRECTORY)
|
||||||
|
{
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
file->vnode->type = FT_DEVICE;
|
||||||
|
}
|
||||||
|
|
||||||
|
file->vnode->data = d_file;
|
||||||
|
file->vnode->size = d_file->size;
|
||||||
|
if (file->flags & O_APPEND)
|
||||||
|
{
|
||||||
|
file->pos = file->vnode->size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file->pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_tmpfs_stat(struct dfs_filesystem *fs,
|
||||||
|
const char *path,
|
||||||
|
struct stat *st)
|
||||||
|
{
|
||||||
|
rt_size_t size;
|
||||||
|
struct tmpfs_file *d_file;
|
||||||
|
struct tmpfs_sb *superblock;
|
||||||
|
|
||||||
|
superblock = (struct tmpfs_sb *)fs->data;
|
||||||
|
d_file = dfs_tmpfs_lookup(superblock, path, &size);
|
||||||
|
|
||||||
|
if (d_file == NULL)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
st->st_dev = 0;
|
||||||
|
st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
|
||||||
|
S_IWUSR | S_IWGRP | S_IWOTH;
|
||||||
|
if (d_file->type == TMPFS_TYPE_DIR)
|
||||||
|
{
|
||||||
|
st->st_mode &= ~S_IFREG;
|
||||||
|
st->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
st->st_size = d_file->size;
|
||||||
|
st->st_mtime = 0;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_tmpfs_getdents(struct dfs_file *file,
|
||||||
|
struct dirent *dirp,
|
||||||
|
uint32_t count)
|
||||||
|
{
|
||||||
|
rt_size_t index, end;
|
||||||
|
struct dirent *d;
|
||||||
|
struct tmpfs_file *d_file, *n_file;
|
||||||
|
rt_list_t *list;
|
||||||
|
struct tmpfs_sb *superblock;
|
||||||
|
|
||||||
|
d_file = (struct tmpfs_file *)file->vnode->data;
|
||||||
|
|
||||||
|
superblock = d_file->sb;
|
||||||
|
RT_ASSERT(superblock != RT_NULL);
|
||||||
|
|
||||||
|
/* make integer count */
|
||||||
|
count = (count / sizeof(struct dirent));
|
||||||
|
if (count == 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
end = file->pos + count;
|
||||||
|
index = 0;
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
rt_list_for_each(list, &d_file->subdirs)
|
||||||
|
{
|
||||||
|
n_file = rt_list_entry(list, struct tmpfs_file, sibling);
|
||||||
|
if (index >= (rt_size_t)file->pos)
|
||||||
|
{
|
||||||
|
d = dirp + count;
|
||||||
|
if (d_file->type == TMPFS_TYPE_FILE)
|
||||||
|
{
|
||||||
|
d->d_type = DT_REG;
|
||||||
|
}
|
||||||
|
if (d_file->type == TMPFS_TYPE_DIR)
|
||||||
|
{
|
||||||
|
d->d_type = DT_DIR;
|
||||||
|
}
|
||||||
|
d->d_namlen = RT_NAME_MAX;
|
||||||
|
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
|
||||||
|
rt_strncpy(d->d_name, n_file->name, TMPFS_NAME_MAX);
|
||||||
|
|
||||||
|
count += 1;
|
||||||
|
file->pos += 1;
|
||||||
|
}
|
||||||
|
index += 1;
|
||||||
|
if (index >= end)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count * sizeof(struct dirent);
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_tmpfs_unlink(struct dfs_filesystem *fs, const char *path)
|
||||||
|
{
|
||||||
|
rt_size_t size;
|
||||||
|
struct tmpfs_sb *superblock;
|
||||||
|
struct tmpfs_file *d_file;
|
||||||
|
|
||||||
|
superblock = (struct tmpfs_sb *)fs->data;
|
||||||
|
RT_ASSERT(superblock != NULL);
|
||||||
|
|
||||||
|
d_file = dfs_tmpfs_lookup(superblock, path, &size);
|
||||||
|
if (d_file == NULL)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
rt_spin_lock(&superblock->lock);
|
||||||
|
rt_list_remove(&(d_file->sibling));
|
||||||
|
rt_spin_unlock(&superblock->lock);
|
||||||
|
|
||||||
|
if (d_file->data != NULL)
|
||||||
|
rt_free(d_file->data);
|
||||||
|
rt_free(d_file);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_tmpfs_rename(struct dfs_filesystem *fs,
|
||||||
|
const char *oldpath,
|
||||||
|
const char *newpath)
|
||||||
|
{
|
||||||
|
struct tmpfs_file *d_file, *p_file;
|
||||||
|
struct tmpfs_sb *superblock;
|
||||||
|
rt_size_t size;
|
||||||
|
char parent_path[DFS_PATH_MAX],file_name[TMPFS_NAME_MAX];
|
||||||
|
|
||||||
|
superblock = (struct tmpfs_sb *)fs->data;
|
||||||
|
RT_ASSERT(superblock != NULL);
|
||||||
|
|
||||||
|
d_file = dfs_tmpfs_lookup(superblock, newpath, &size);
|
||||||
|
if (d_file != NULL)
|
||||||
|
return -EEXIST;
|
||||||
|
|
||||||
|
d_file = dfs_tmpfs_lookup(superblock, oldpath, &size);
|
||||||
|
if (d_file == NULL)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
/* find parent file */
|
||||||
|
_path_separate(newpath, parent_path, file_name);
|
||||||
|
if (file_name[0] == '\0') /* it's root dir */
|
||||||
|
return -ENOENT;
|
||||||
|
/* open parent directory */
|
||||||
|
p_file = dfs_tmpfs_lookup(superblock, parent_path, &size);
|
||||||
|
RT_ASSERT(p_file != NULL);
|
||||||
|
|
||||||
|
rt_spin_lock(&superblock->lock);
|
||||||
|
rt_list_remove(&(d_file->sibling));
|
||||||
|
rt_spin_unlock(&superblock->lock);
|
||||||
|
|
||||||
|
strncpy(d_file->name, file_name, TMPFS_NAME_MAX);
|
||||||
|
|
||||||
|
rt_spin_lock(&superblock->lock);
|
||||||
|
rt_list_insert_after(&(p_file->subdirs), &(d_file->sibling));
|
||||||
|
rt_spin_unlock(&superblock->lock);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dfs_file_ops _tmp_fops =
|
||||||
|
{
|
||||||
|
dfs_tmpfs_open,
|
||||||
|
dfs_tmpfs_close,
|
||||||
|
dfs_tmpfs_ioctl,
|
||||||
|
dfs_tmpfs_read,
|
||||||
|
dfs_tmpfs_write,
|
||||||
|
NULL, /* flush */
|
||||||
|
dfs_tmpfs_lseek,
|
||||||
|
dfs_tmpfs_getdents,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct dfs_filesystem_ops _tmpfs =
|
||||||
|
{
|
||||||
|
"tmp",
|
||||||
|
DFS_FS_FLAG_DEFAULT,
|
||||||
|
&_tmp_fops,
|
||||||
|
|
||||||
|
dfs_tmpfs_mount,
|
||||||
|
dfs_tmpfs_unmount,
|
||||||
|
NULL, /* mkfs */
|
||||||
|
dfs_tmpfs_statfs,
|
||||||
|
|
||||||
|
dfs_tmpfs_unlink,
|
||||||
|
dfs_tmpfs_stat,
|
||||||
|
dfs_tmpfs_rename,
|
||||||
|
};
|
||||||
|
|
||||||
|
int dfs_tmpfs_init(void)
|
||||||
|
{
|
||||||
|
/* register tmp file system */
|
||||||
|
dfs_register(&_tmpfs);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
48
components/dfs/dfs_v1/filesystems/tmpfs/dfs_tmpfs.h
Normal file
48
components/dfs/dfs_v1/filesystems/tmpfs/dfs_tmpfs.h
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2022-10-24 flybreak the first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DFS_TMPFS_H__
|
||||||
|
#define __DFS_TMPFS_H__
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
#define TMPFS_NAME_MAX 32
|
||||||
|
#define TMPFS_MAGIC 0x0B0B0B0B
|
||||||
|
|
||||||
|
#define TMPFS_TYPE_FILE 0x00
|
||||||
|
#define TMPFS_TYPE_DIR 0x01
|
||||||
|
|
||||||
|
struct tmpfs_sb;
|
||||||
|
|
||||||
|
struct tmpfs_file
|
||||||
|
{
|
||||||
|
rt_uint32_t type; /* file type */
|
||||||
|
char name[TMPFS_NAME_MAX]; /* file name */
|
||||||
|
rt_list_t subdirs; /* file subdir list */
|
||||||
|
rt_list_t sibling; /* file sibling list */
|
||||||
|
struct tmpfs_sb *sb; /* superblock ptr */
|
||||||
|
rt_uint8_t *data; /* file date ptr */
|
||||||
|
rt_size_t size; /* file size */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct tmpfs_sb
|
||||||
|
{
|
||||||
|
rt_uint32_t magic; /* TMPFS_MAGIC */
|
||||||
|
struct tmpfs_file root; /* root dir */
|
||||||
|
rt_size_t df_size; /* df size */
|
||||||
|
rt_list_t sibling; /* sb sibling list */
|
||||||
|
struct rt_spinlock lock; /* tmpfs lock */
|
||||||
|
};
|
||||||
|
|
||||||
|
int dfs_tmpfs_init(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
119
components/dfs/dfs_v1/include/dfs.h
Normal file
119
components/dfs/dfs_v1/include/dfs.h
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2005-02-22 Bernard The first version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DFS_H__
|
||||||
|
#define __DFS_H__
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/statfs.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <rtdevice.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DFS_FILESYSTEMS_MAX
|
||||||
|
#define DFS_FILESYSTEMS_MAX 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DFS_FD_MAX
|
||||||
|
#define DFS_FD_MAX 16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* skip stdin/stdout/stderr normally
|
||||||
|
*/
|
||||||
|
#ifndef DFS_STDIO_OFFSET
|
||||||
|
#define DFS_STDIO_OFFSET 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DFS_PATH_MAX
|
||||||
|
#define DFS_PATH_MAX DIRENT_NAME_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SECTOR_SIZE
|
||||||
|
#define SECTOR_SIZE 512
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DFS_FILESYSTEM_TYPES_MAX
|
||||||
|
#define DFS_FILESYSTEM_TYPES_MAX 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DFS_FS_FLAG_DEFAULT 0x00 /* default flag */
|
||||||
|
#define DFS_FS_FLAG_FULLPATH 0x01 /* set full path to underlaying file system */
|
||||||
|
|
||||||
|
/* File types */
|
||||||
|
#define FT_REGULAR 0 /* regular file */
|
||||||
|
#define FT_SOCKET 1 /* socket file */
|
||||||
|
#define FT_DIRECTORY 2 /* directory */
|
||||||
|
#define FT_USER 3 /* user defined */
|
||||||
|
#define FT_DEVICE 4 /* device */
|
||||||
|
|
||||||
|
/* File flags */
|
||||||
|
#define DFS_F_OPEN 0x01000000
|
||||||
|
#define DFS_F_DIRECTORY 0x02000000
|
||||||
|
#define DFS_F_EOF 0x04000000
|
||||||
|
#define DFS_F_ERR 0x08000000
|
||||||
|
|
||||||
|
struct dfs_fdtable
|
||||||
|
{
|
||||||
|
uint32_t maxfd;
|
||||||
|
struct dfs_file **fds;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Initialization of dfs */
|
||||||
|
int dfs_init(void);
|
||||||
|
|
||||||
|
char *dfs_normalize_path(const char *directory, const char *filename);
|
||||||
|
const char *dfs_subdir(const char *directory, const char *filename);
|
||||||
|
|
||||||
|
int fd_is_open(const char *pathname);
|
||||||
|
struct dfs_fdtable *dfs_fdtable_get(void);
|
||||||
|
|
||||||
|
void dfs_lock(void);
|
||||||
|
void dfs_unlock(void);
|
||||||
|
|
||||||
|
void dfs_file_lock(void);
|
||||||
|
void dfs_file_unlock(void);
|
||||||
|
|
||||||
|
void dfs_fm_lock(void);
|
||||||
|
void dfs_fm_unlock(void);
|
||||||
|
|
||||||
|
#ifdef DFS_USING_POSIX
|
||||||
|
|
||||||
|
/* FD APIs */
|
||||||
|
int fdt_fd_new(struct dfs_fdtable *fdt);
|
||||||
|
struct dfs_file *fdt_fd_get(struct dfs_fdtable* fdt, int fd);
|
||||||
|
void fdt_fd_release(struct dfs_fdtable* fdt, int fd);
|
||||||
|
|
||||||
|
int fd_new(void);
|
||||||
|
struct dfs_file *fd_get(int fd);
|
||||||
|
void fd_release(int fd);
|
||||||
|
|
||||||
|
void fd_init(struct dfs_file *fd);
|
||||||
|
int fd_associate(struct dfs_fdtable *fdt, int fd, struct dfs_file *file);
|
||||||
|
int fd_get_fd_index(struct dfs_file *file);
|
||||||
|
|
||||||
|
struct dfs_fdtable *dfs_fdtable_get(void);
|
||||||
|
struct dfs_fdtable *dfs_fdtable_get_global(void);
|
||||||
|
#endif /* DFS_USING_POSIX */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
104
components/dfs/dfs_v1/include/dfs_file.h
Normal file
104
components/dfs/dfs_v1/include/dfs_file.h
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2005-01-26 Bernard The first version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DFS_FILE_H__
|
||||||
|
#define __DFS_FILE_H__
|
||||||
|
|
||||||
|
#include <dfs.h>
|
||||||
|
#include <dfs_fs.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct rt_pollreq;
|
||||||
|
|
||||||
|
struct dfs_file_ops
|
||||||
|
{
|
||||||
|
int (*open) (struct dfs_file *fd);
|
||||||
|
int (*close) (struct dfs_file *fd);
|
||||||
|
int (*ioctl) (struct dfs_file *fd, int cmd, void *args);
|
||||||
|
int (*read) (struct dfs_file *fd, void *buf, size_t count);
|
||||||
|
int (*write) (struct dfs_file *fd, const void *buf, size_t count);
|
||||||
|
int (*flush) (struct dfs_file *fd);
|
||||||
|
int (*lseek) (struct dfs_file *fd, off_t offset);
|
||||||
|
int (*getdents) (struct dfs_file *fd, struct dirent *dirp, uint32_t count);
|
||||||
|
|
||||||
|
int (*poll) (struct dfs_file *fd, struct rt_pollreq *req);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* file descriptor */
|
||||||
|
#define DFS_FD_MAGIC 0xfdfd
|
||||||
|
|
||||||
|
struct dfs_vnode
|
||||||
|
{
|
||||||
|
uint16_t type; /* Type (regular or socket) */
|
||||||
|
|
||||||
|
char *path; /* Name (below mount point) */
|
||||||
|
char *fullpath; /* Full path is hash key */
|
||||||
|
int ref_count; /* Descriptor reference count */
|
||||||
|
rt_list_t list; /* The node of vnode hash table */
|
||||||
|
|
||||||
|
struct dfs_filesystem *fs;
|
||||||
|
const struct dfs_file_ops *fops;
|
||||||
|
uint32_t flags; /* self flags, is dir etc.. */
|
||||||
|
|
||||||
|
size_t size; /* Size in bytes */
|
||||||
|
void *data; /* Specific file system data */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dfs_file
|
||||||
|
{
|
||||||
|
uint16_t magic; /* file descriptor magic number */
|
||||||
|
uint32_t flags; /* Descriptor flags */
|
||||||
|
int ref_count; /* Descriptor reference count */
|
||||||
|
off_t pos; /* Current file position */
|
||||||
|
struct dfs_vnode *vnode; /* file node struct */
|
||||||
|
void *data; /* Specific fd data */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dfs_mmap2_args
|
||||||
|
{
|
||||||
|
void *addr;
|
||||||
|
size_t length;
|
||||||
|
int prot;
|
||||||
|
int flags;
|
||||||
|
off_t pgoffset;
|
||||||
|
|
||||||
|
void *ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
void dfs_vnode_mgr_init(void);
|
||||||
|
int dfs_file_is_open(const char *pathname);
|
||||||
|
int dfs_file_open(struct dfs_file *fd, const char *path, int flags);
|
||||||
|
int dfs_file_close(struct dfs_file *fd);
|
||||||
|
int dfs_file_ioctl(struct dfs_file *fd, int cmd, void *args);
|
||||||
|
int dfs_file_read(struct dfs_file *fd, void *buf, size_t len);
|
||||||
|
int dfs_file_getdents(struct dfs_file *fd, struct dirent *dirp, size_t nbytes);
|
||||||
|
int dfs_file_unlink(const char *path);
|
||||||
|
int dfs_file_write(struct dfs_file *fd, const void *buf, size_t len);
|
||||||
|
int dfs_file_flush(struct dfs_file *fd);
|
||||||
|
int dfs_file_lseek(struct dfs_file *fd, off_t offset);
|
||||||
|
|
||||||
|
int dfs_file_stat(const char *path, struct stat *buf);
|
||||||
|
int dfs_file_rename(const char *oldpath, const char *newpath);
|
||||||
|
int dfs_file_ftruncate(struct dfs_file *fd, off_t length);
|
||||||
|
int dfs_file_mmap2(struct dfs_file *fd, struct dfs_mmap2_args *mmap2);
|
||||||
|
|
||||||
|
/* 0x5254 is just a magic number to make these relatively unique ("RT") */
|
||||||
|
#define RT_FIOFTRUNCATE 0x52540000U
|
||||||
|
#define RT_FIOGETADDR 0x52540001U
|
||||||
|
#define RT_FIOMMAP2 0x52540002U
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
102
components/dfs/dfs_v1/include/dfs_fs.h
Normal file
102
components/dfs/dfs_v1/include/dfs_fs.h
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2005-02-22 Bernard The first version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DFS_FS_H__
|
||||||
|
#define __DFS_FS_H__
|
||||||
|
|
||||||
|
#include <dfs.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/errno.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Pre-declaration */
|
||||||
|
struct dfs_filesystem;
|
||||||
|
struct dfs_file;
|
||||||
|
|
||||||
|
/* File system operations */
|
||||||
|
struct dfs_filesystem_ops
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
uint32_t flags; /* flags for file system operations */
|
||||||
|
|
||||||
|
/* operations for file */
|
||||||
|
const struct dfs_file_ops *fops;
|
||||||
|
|
||||||
|
/* mount and unmount file system */
|
||||||
|
int (*mount) (struct dfs_filesystem *fs, unsigned long rwflag, const void *data);
|
||||||
|
int (*unmount) (struct dfs_filesystem *fs);
|
||||||
|
|
||||||
|
/* make a file system */
|
||||||
|
int (*mkfs) (rt_device_t dev_id, const char *fs_name);
|
||||||
|
int (*statfs) (struct dfs_filesystem *fs, struct statfs *buf);
|
||||||
|
|
||||||
|
int (*unlink) (struct dfs_filesystem *fs, const char *pathname);
|
||||||
|
int (*stat) (struct dfs_filesystem *fs, const char *filename, struct stat *buf);
|
||||||
|
int (*rename) (struct dfs_filesystem *fs, const char *oldpath, const char *newpath);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Mounted file system */
|
||||||
|
struct dfs_filesystem
|
||||||
|
{
|
||||||
|
rt_device_t dev_id; /* Attached device */
|
||||||
|
|
||||||
|
char *path; /* File system mount point */
|
||||||
|
const struct dfs_filesystem_ops *ops; /* Operations for file system type */
|
||||||
|
|
||||||
|
void *data; /* Specific file system data */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* file system partition table */
|
||||||
|
struct dfs_partition
|
||||||
|
{
|
||||||
|
uint8_t type; /* file system type */
|
||||||
|
off_t offset; /* partition start offset */
|
||||||
|
size_t size; /* partition size */
|
||||||
|
rt_sem_t lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* mount table */
|
||||||
|
struct dfs_mount_tbl
|
||||||
|
{
|
||||||
|
const char *device_name;
|
||||||
|
const char *path;
|
||||||
|
const char *filesystemtype;
|
||||||
|
unsigned long rwflag;
|
||||||
|
const void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
int dfs_register(const struct dfs_filesystem_ops *ops);
|
||||||
|
struct dfs_filesystem *dfs_filesystem_lookup(const char *path);
|
||||||
|
const char *dfs_filesystem_get_mounted_path(struct rt_device *device);
|
||||||
|
|
||||||
|
int dfs_filesystem_get_partition(struct dfs_partition *part,
|
||||||
|
uint8_t *buf,
|
||||||
|
uint32_t pindex);
|
||||||
|
|
||||||
|
int dfs_mount(const char *device_name,
|
||||||
|
const char *path,
|
||||||
|
const char *filesystemtype,
|
||||||
|
unsigned long rwflag,
|
||||||
|
const void *data);
|
||||||
|
int dfs_unmount(const char *specialfile);
|
||||||
|
|
||||||
|
int dfs_mkfs(const char *fs_name, const char *device_name);
|
||||||
|
int dfs_statfs(const char *path, struct statfs *buffer);
|
||||||
|
int dfs_mount_device(rt_device_t dev);
|
||||||
|
int dfs_unmount_device(rt_device_t dev);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
28
components/dfs/dfs_v1/include/dfs_private.h
Normal file
28
components/dfs/dfs_v1/include/dfs_private.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DFS_PRIVATE_H__
|
||||||
|
#define DFS_PRIVATE_H__
|
||||||
|
|
||||||
|
#include <dfs.h>
|
||||||
|
|
||||||
|
#define DBG_TAG "DFS"
|
||||||
|
#define DBG_LVL DBG_INFO
|
||||||
|
#include <rtdbg.h>
|
||||||
|
|
||||||
|
#define NO_WORKING_DIR "system does not support working directory\n"
|
||||||
|
|
||||||
|
/* extern variable */
|
||||||
|
extern const struct dfs_filesystem_ops *filesystem_operation_table[];
|
||||||
|
extern struct dfs_filesystem filesystem_table[];
|
||||||
|
extern const struct dfs_mount_tbl mount_table[];
|
||||||
|
|
||||||
|
extern char working_directory[];
|
||||||
|
|
||||||
|
#endif
|
975
components/dfs/dfs_v1/src/dfs.c
Normal file
975
components/dfs/dfs_v1/src/dfs.c
Normal file
|
@ -0,0 +1,975 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2005-02-22 Bernard The first version.
|
||||||
|
* 2017-12-11 Bernard Use rt_free to instead of free in fd_is_open().
|
||||||
|
* 2018-03-20 Heyuanjie dynamic allocation FD
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dfs.h>
|
||||||
|
#include <dfs_fs.h>
|
||||||
|
#include <dfs_file.h>
|
||||||
|
#include "dfs_private.h"
|
||||||
|
#ifdef RT_USING_SMART
|
||||||
|
#include <lwp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RT_USING_POSIX_STDIO
|
||||||
|
#include <libc.h>
|
||||||
|
#endif /* RT_USING_POSIX_STDIO */
|
||||||
|
|
||||||
|
/* Global variables */
|
||||||
|
const struct dfs_filesystem_ops *filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX];
|
||||||
|
struct dfs_filesystem filesystem_table[DFS_FILESYSTEMS_MAX];
|
||||||
|
|
||||||
|
/* device filesystem lock */
|
||||||
|
static struct rt_mutex fslock;
|
||||||
|
static struct rt_mutex fdlock;
|
||||||
|
|
||||||
|
#ifdef DFS_USING_WORKDIR
|
||||||
|
char working_directory[DFS_PATH_MAX] = {"/"};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct dfs_fdtable _fdtab;
|
||||||
|
static int fd_alloc(struct dfs_fdtable *fdt, int startfd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup DFS
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will initialize device file system.
|
||||||
|
*/
|
||||||
|
int dfs_init(void)
|
||||||
|
{
|
||||||
|
static rt_bool_t init_ok = RT_FALSE;
|
||||||
|
|
||||||
|
if (init_ok)
|
||||||
|
{
|
||||||
|
rt_kprintf("dfs already init.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* init vnode hash table */
|
||||||
|
dfs_vnode_mgr_init();
|
||||||
|
|
||||||
|
/* clear filesystem operations table */
|
||||||
|
rt_memset((void *)filesystem_operation_table, 0, sizeof(filesystem_operation_table));
|
||||||
|
/* clear filesystem table */
|
||||||
|
rt_memset(filesystem_table, 0, sizeof(filesystem_table));
|
||||||
|
/* clean fd table */
|
||||||
|
rt_memset(&_fdtab, 0, sizeof(_fdtab));
|
||||||
|
|
||||||
|
/* create device filesystem lock */
|
||||||
|
rt_mutex_init(&fslock, "fslock", RT_IPC_FLAG_PRIO);
|
||||||
|
rt_mutex_init(&fdlock, "fdlock", RT_IPC_FLAG_PRIO);
|
||||||
|
|
||||||
|
#ifdef DFS_USING_WORKDIR
|
||||||
|
/* set current working directory */
|
||||||
|
rt_memset(working_directory, 0, sizeof(working_directory));
|
||||||
|
working_directory[0] = '/';
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RT_USING_DFS_TMPFS
|
||||||
|
{
|
||||||
|
extern int dfs_tmpfs_init(void);
|
||||||
|
dfs_tmpfs_init();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RT_USING_DFS_DEVFS
|
||||||
|
{
|
||||||
|
extern int devfs_init(void);
|
||||||
|
|
||||||
|
/* if enable devfs, initialize and mount it as soon as possible */
|
||||||
|
devfs_init();
|
||||||
|
|
||||||
|
dfs_mount(NULL, "/dev", "devfs", 0, 0);
|
||||||
|
}
|
||||||
|
#if defined(RT_USING_DEV_BUS) && defined(RT_USING_DFS_TMPFS)
|
||||||
|
mkdir("/dev/shm", 0x777);
|
||||||
|
if (dfs_mount(RT_NULL, "/dev/shm", "tmp", 0, 0) != 0)
|
||||||
|
{
|
||||||
|
rt_kprintf("Dir /dev/shm mount failed!\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
init_ok = RT_TRUE;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
INIT_PREV_EXPORT(dfs_init);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will lock device file system.
|
||||||
|
*
|
||||||
|
* @note please don't invoke it on ISR.
|
||||||
|
*/
|
||||||
|
void dfs_lock(void)
|
||||||
|
{
|
||||||
|
rt_err_t result = -RT_EBUSY;
|
||||||
|
|
||||||
|
while (result == -RT_EBUSY)
|
||||||
|
{
|
||||||
|
result = rt_mutex_take(&fslock, RT_WAITING_FOREVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != RT_EOK)
|
||||||
|
{
|
||||||
|
RT_ASSERT(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dfs_file_lock(void)
|
||||||
|
{
|
||||||
|
rt_err_t result = -RT_EBUSY;
|
||||||
|
|
||||||
|
while (result == -RT_EBUSY)
|
||||||
|
{
|
||||||
|
result = rt_mutex_take(&fdlock, RT_WAITING_FOREVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != RT_EOK)
|
||||||
|
{
|
||||||
|
RT_ASSERT(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will lock device file system.
|
||||||
|
*
|
||||||
|
* @note please don't invoke it on ISR.
|
||||||
|
*/
|
||||||
|
void dfs_unlock(void)
|
||||||
|
{
|
||||||
|
rt_mutex_release(&fslock);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DFS_USING_POSIX
|
||||||
|
|
||||||
|
void dfs_file_unlock(void)
|
||||||
|
{
|
||||||
|
rt_mutex_release(&fdlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fd_slot_expand(struct dfs_fdtable *fdt, int fd)
|
||||||
|
{
|
||||||
|
int nr;
|
||||||
|
int index;
|
||||||
|
struct dfs_file **fds = NULL;
|
||||||
|
|
||||||
|
if (fd < fdt->maxfd)
|
||||||
|
{
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
if (fd >= DFS_FD_MAX)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nr = ((fd + 4) & ~3);
|
||||||
|
if (nr > DFS_FD_MAX)
|
||||||
|
{
|
||||||
|
nr = DFS_FD_MAX;
|
||||||
|
}
|
||||||
|
fds = (struct dfs_file **)rt_realloc(fdt->fds, nr * sizeof(struct dfs_file *));
|
||||||
|
if (!fds)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clean the new allocated fds */
|
||||||
|
for (index = fdt->maxfd; index < nr; index++)
|
||||||
|
{
|
||||||
|
fds[index] = NULL;
|
||||||
|
}
|
||||||
|
fdt->fds = fds;
|
||||||
|
fdt->maxfd = nr;
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fd_slot_alloc(struct dfs_fdtable *fdt, int startfd)
|
||||||
|
{
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
/* find an empty fd slot */
|
||||||
|
for (idx = startfd; idx < (int)fdt->maxfd; idx++)
|
||||||
|
{
|
||||||
|
if (fdt->fds[idx] == RT_NULL)
|
||||||
|
{
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
idx = fdt->maxfd;
|
||||||
|
if (idx < startfd)
|
||||||
|
{
|
||||||
|
idx = startfd;
|
||||||
|
}
|
||||||
|
if (fd_slot_expand(fdt, idx) < 0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
static int fd_alloc(struct dfs_fdtable *fdt, int startfd)
|
||||||
|
{
|
||||||
|
int idx;
|
||||||
|
struct dfs_file *fd = NULL;
|
||||||
|
|
||||||
|
idx = fd_slot_alloc(fdt, startfd);
|
||||||
|
|
||||||
|
/* allocate 'struct dfs_file' */
|
||||||
|
if (idx < 0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fd = (struct dfs_file *)rt_calloc(1, sizeof(struct dfs_file));
|
||||||
|
if (!fd)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fd->ref_count = 1;
|
||||||
|
fd->magic = DFS_FD_MAGIC;
|
||||||
|
fd->vnode = NULL;
|
||||||
|
fdt->fds[idx] = fd;
|
||||||
|
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup Fd
|
||||||
|
* This function will allocate a file descriptor.
|
||||||
|
*
|
||||||
|
* @return -1 on failed or the allocated file descriptor.
|
||||||
|
*/
|
||||||
|
int fdt_fd_new(struct dfs_fdtable *fdt)
|
||||||
|
{
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
/* lock filesystem */
|
||||||
|
dfs_file_lock();
|
||||||
|
|
||||||
|
/* find an empty fd entry */
|
||||||
|
idx = fd_alloc(fdt, DFS_STDIO_OFFSET);
|
||||||
|
|
||||||
|
/* can't find an empty fd entry */
|
||||||
|
if (idx < 0)
|
||||||
|
{
|
||||||
|
LOG_E("DFS fd new is failed! Could not found an empty fd entry.");
|
||||||
|
}
|
||||||
|
|
||||||
|
dfs_file_unlock();
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fd_new(void)
|
||||||
|
{
|
||||||
|
struct dfs_fdtable *fdt = NULL;
|
||||||
|
|
||||||
|
fdt = dfs_fdtable_get();
|
||||||
|
return fdt_fd_new(fdt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup Fd
|
||||||
|
*
|
||||||
|
* This function will return a file descriptor structure according to file
|
||||||
|
* descriptor.
|
||||||
|
*
|
||||||
|
* @return NULL on on this file descriptor or the file descriptor structure
|
||||||
|
* pointer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct dfs_file *fdt_fd_get(struct dfs_fdtable* fdt, int fd)
|
||||||
|
{
|
||||||
|
struct dfs_file *d;
|
||||||
|
|
||||||
|
if (fd < 0 || fd >= (int)fdt->maxfd)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dfs_file_lock();
|
||||||
|
d = fdt->fds[fd];
|
||||||
|
|
||||||
|
/* check dfs_file valid or not */
|
||||||
|
if ((d == NULL) || (d->magic != DFS_FD_MAGIC))
|
||||||
|
{
|
||||||
|
dfs_file_unlock();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dfs_file_unlock();
|
||||||
|
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dfs_file *fd_get(int fd)
|
||||||
|
{
|
||||||
|
struct dfs_fdtable *fdt;
|
||||||
|
|
||||||
|
fdt = dfs_fdtable_get();
|
||||||
|
return fdt_fd_get(fdt, fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup Fd
|
||||||
|
*
|
||||||
|
* This function will put the file descriptor.
|
||||||
|
*/
|
||||||
|
void fdt_fd_release(struct dfs_fdtable* fdt, int fd)
|
||||||
|
{
|
||||||
|
struct dfs_file *fd_slot = NULL;
|
||||||
|
|
||||||
|
RT_ASSERT(fdt != NULL);
|
||||||
|
|
||||||
|
dfs_file_lock();
|
||||||
|
|
||||||
|
if ((fd < 0) || (fd >= fdt->maxfd))
|
||||||
|
{
|
||||||
|
dfs_file_unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd_slot = fdt->fds[fd];
|
||||||
|
if (fd_slot == NULL)
|
||||||
|
{
|
||||||
|
dfs_file_unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fdt->fds[fd] = NULL;
|
||||||
|
|
||||||
|
/* check fd */
|
||||||
|
RT_ASSERT(fd_slot->magic == DFS_FD_MAGIC);
|
||||||
|
|
||||||
|
fd_slot->ref_count--;
|
||||||
|
|
||||||
|
/* clear this fd entry */
|
||||||
|
if (fd_slot->ref_count == 0)
|
||||||
|
{
|
||||||
|
struct dfs_vnode *vnode = fd_slot->vnode;
|
||||||
|
if (vnode)
|
||||||
|
{
|
||||||
|
vnode->ref_count--;
|
||||||
|
if(vnode->ref_count == 0)
|
||||||
|
{
|
||||||
|
rt_free(vnode);
|
||||||
|
fd_slot->vnode = RT_NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rt_free(fd_slot);
|
||||||
|
}
|
||||||
|
dfs_file_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void fd_release(int fd)
|
||||||
|
{
|
||||||
|
struct dfs_fdtable *fdt;
|
||||||
|
|
||||||
|
fdt = dfs_fdtable_get();
|
||||||
|
fdt_fd_release(fdt, fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_err_t sys_dup(int oldfd)
|
||||||
|
{
|
||||||
|
int newfd = -1;
|
||||||
|
struct dfs_fdtable *fdt = NULL;
|
||||||
|
|
||||||
|
dfs_file_lock();
|
||||||
|
/* check old fd */
|
||||||
|
fdt = dfs_fdtable_get();
|
||||||
|
if ((oldfd < 0) || (oldfd >= fdt->maxfd))
|
||||||
|
{
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if (!fdt->fds[oldfd])
|
||||||
|
{
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
/* get a new fd */
|
||||||
|
newfd = fd_slot_alloc(fdt, DFS_STDIO_OFFSET);
|
||||||
|
if (newfd >= 0)
|
||||||
|
{
|
||||||
|
fdt->fds[newfd] = fdt->fds[oldfd];
|
||||||
|
/* inc ref_count */
|
||||||
|
fdt->fds[newfd]->ref_count++;
|
||||||
|
}
|
||||||
|
exit:
|
||||||
|
dfs_file_unlock();
|
||||||
|
return newfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* DFS_USING_POSIX */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup Fd
|
||||||
|
*
|
||||||
|
* This function will return whether this file has been opend.
|
||||||
|
*
|
||||||
|
* @param pathname the file path name.
|
||||||
|
*
|
||||||
|
* @return 0 on file has been open successfully, -1 on open failed.
|
||||||
|
*/
|
||||||
|
int fd_is_open(const char *pathname)
|
||||||
|
{
|
||||||
|
char *fullpath;
|
||||||
|
unsigned int index;
|
||||||
|
struct dfs_filesystem *fs;
|
||||||
|
struct dfs_file *fd;
|
||||||
|
struct dfs_fdtable *fdt;
|
||||||
|
|
||||||
|
fdt = dfs_fdtable_get();
|
||||||
|
fullpath = dfs_normalize_path(NULL, pathname);
|
||||||
|
if (fullpath != NULL)
|
||||||
|
{
|
||||||
|
char *mountpath;
|
||||||
|
fs = dfs_filesystem_lookup(fullpath);
|
||||||
|
if (fs == NULL)
|
||||||
|
{
|
||||||
|
/* can't find mounted file system */
|
||||||
|
rt_free(fullpath);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get file path name under mounted file system */
|
||||||
|
if (fs->path[0] == '/' && fs->path[1] == '\0')
|
||||||
|
mountpath = fullpath;
|
||||||
|
else
|
||||||
|
mountpath = fullpath + strlen(fs->path);
|
||||||
|
|
||||||
|
dfs_lock();
|
||||||
|
|
||||||
|
for (index = 0; index < fdt->maxfd; index++)
|
||||||
|
{
|
||||||
|
fd = fdt->fds[index];
|
||||||
|
if (fd == NULL || fd->vnode->fops == NULL || fd->vnode->path == NULL) continue;
|
||||||
|
|
||||||
|
if (fd->vnode->fs == fs && strcmp(fd->vnode->path, mountpath) == 0)
|
||||||
|
{
|
||||||
|
/* found file in file descriptor table */
|
||||||
|
rt_free(fullpath);
|
||||||
|
dfs_unlock();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dfs_unlock();
|
||||||
|
|
||||||
|
rt_free(fullpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_err_t sys_dup2(int oldfd, int newfd)
|
||||||
|
{
|
||||||
|
struct dfs_fdtable *fdt = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
int retfd = -1;
|
||||||
|
|
||||||
|
dfs_file_lock();
|
||||||
|
/* check old fd */
|
||||||
|
fdt = dfs_fdtable_get();
|
||||||
|
if ((oldfd < 0) || (oldfd >= fdt->maxfd))
|
||||||
|
{
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if (!fdt->fds[oldfd])
|
||||||
|
{
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if (newfd < 0)
|
||||||
|
{
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if (newfd >= fdt->maxfd)
|
||||||
|
{
|
||||||
|
newfd = fd_slot_expand(fdt, newfd);
|
||||||
|
if (newfd < 0)
|
||||||
|
{
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fdt->fds[newfd] == fdt->fds[oldfd])
|
||||||
|
{
|
||||||
|
/* ok, return newfd */
|
||||||
|
retfd = newfd;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fdt->fds[newfd])
|
||||||
|
{
|
||||||
|
ret = dfs_file_close(fdt->fds[newfd]);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
fd_release(newfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
fdt->fds[newfd] = fdt->fds[oldfd];
|
||||||
|
/* inc ref_count */
|
||||||
|
fdt->fds[newfd]->ref_count++;
|
||||||
|
retfd = newfd;
|
||||||
|
exit:
|
||||||
|
dfs_file_unlock();
|
||||||
|
return retfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fd_get_fd_index_form_fdt(struct dfs_fdtable *fdt, struct dfs_file *file)
|
||||||
|
{
|
||||||
|
int fd = -1;
|
||||||
|
|
||||||
|
if (file == RT_NULL)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dfs_file_lock();
|
||||||
|
|
||||||
|
for(int index = 0; index < (int)fdt->maxfd; index++)
|
||||||
|
{
|
||||||
|
if(fdt->fds[index] == file)
|
||||||
|
{
|
||||||
|
fd = index;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dfs_file_unlock();
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fd_get_fd_index(struct dfs_file *file)
|
||||||
|
{
|
||||||
|
struct dfs_fdtable *fdt;
|
||||||
|
|
||||||
|
fdt = dfs_fdtable_get();
|
||||||
|
return fd_get_fd_index_form_fdt(fdt, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
int fd_associate(struct dfs_fdtable *fdt, int fd, struct dfs_file *file)
|
||||||
|
{
|
||||||
|
int retfd = -1;
|
||||||
|
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
return retfd;
|
||||||
|
}
|
||||||
|
if (!fdt)
|
||||||
|
{
|
||||||
|
return retfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
dfs_file_lock();
|
||||||
|
/* check old fd */
|
||||||
|
if ((fd < 0) || (fd >= fdt->maxfd))
|
||||||
|
{
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fdt->fds[fd])
|
||||||
|
{
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
/* inc ref_count */
|
||||||
|
file->ref_count++;
|
||||||
|
fdt->fds[fd] = file;
|
||||||
|
retfd = fd;
|
||||||
|
exit:
|
||||||
|
dfs_file_unlock();
|
||||||
|
return retfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fd_init(struct dfs_file *fd)
|
||||||
|
{
|
||||||
|
if (fd)
|
||||||
|
{
|
||||||
|
fd->magic = DFS_FD_MAGIC;
|
||||||
|
fd->ref_count = 1;
|
||||||
|
fd->pos = 0;
|
||||||
|
fd->vnode = NULL;
|
||||||
|
fd->data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will return a sub-path name under directory.
|
||||||
|
*
|
||||||
|
* @param directory the parent directory.
|
||||||
|
* @param filename the filename.
|
||||||
|
*
|
||||||
|
* @return the subdir pointer in filename
|
||||||
|
*/
|
||||||
|
const char *dfs_subdir(const char *directory, const char *filename)
|
||||||
|
{
|
||||||
|
const char *dir;
|
||||||
|
|
||||||
|
if (strlen(directory) == strlen(filename)) /* it's a same path */
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dir = filename + strlen(directory);
|
||||||
|
if ((*dir != '/') && (dir != filename))
|
||||||
|
{
|
||||||
|
dir --;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
RTM_EXPORT(dfs_subdir);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will normalize a path according to specified parent directory
|
||||||
|
* and file name.
|
||||||
|
*
|
||||||
|
* @param directory the parent path
|
||||||
|
* @param filename the file name
|
||||||
|
*
|
||||||
|
* @return the built full file path (absolute path)
|
||||||
|
*/
|
||||||
|
char *dfs_normalize_path(const char *directory, const char *filename)
|
||||||
|
{
|
||||||
|
char *fullpath;
|
||||||
|
char *dst0, *dst, *src;
|
||||||
|
|
||||||
|
/* check parameters */
|
||||||
|
RT_ASSERT(filename != NULL);
|
||||||
|
|
||||||
|
#ifdef DFS_USING_WORKDIR
|
||||||
|
if (directory == NULL) /* shall use working directory */
|
||||||
|
{
|
||||||
|
#ifdef RT_USING_SMART
|
||||||
|
directory = lwp_getcwd();
|
||||||
|
#else
|
||||||
|
directory = &working_directory[0];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if ((directory == NULL) && (filename[0] != '/'))
|
||||||
|
{
|
||||||
|
rt_kprintf(NO_WORKING_DIR);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (filename[0] != '/') /* it's a absolute path, use it directly */
|
||||||
|
{
|
||||||
|
fullpath = (char *)rt_malloc(strlen(directory) + strlen(filename) + 2);
|
||||||
|
|
||||||
|
if (fullpath == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* join path and file name */
|
||||||
|
rt_snprintf(fullpath, strlen(directory) + strlen(filename) + 2,
|
||||||
|
"%s/%s", directory, filename);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fullpath = rt_strdup(filename); /* copy string */
|
||||||
|
|
||||||
|
if (fullpath == NULL)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
src = fullpath;
|
||||||
|
dst = fullpath;
|
||||||
|
|
||||||
|
dst0 = dst;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
char c = *src;
|
||||||
|
|
||||||
|
if (c == '.')
|
||||||
|
{
|
||||||
|
if (!src[1]) src++; /* '.' and ends */
|
||||||
|
else if (src[1] == '/')
|
||||||
|
{
|
||||||
|
/* './' case */
|
||||||
|
src += 2;
|
||||||
|
|
||||||
|
while ((*src == '/') && (*src != '\0'))
|
||||||
|
src++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (src[1] == '.')
|
||||||
|
{
|
||||||
|
if (!src[2])
|
||||||
|
{
|
||||||
|
/* '..' and ends case */
|
||||||
|
src += 2;
|
||||||
|
goto up_one;
|
||||||
|
}
|
||||||
|
else if (src[2] == '/')
|
||||||
|
{
|
||||||
|
/* '../' case */
|
||||||
|
src += 3;
|
||||||
|
|
||||||
|
while ((*src == '/') && (*src != '\0'))
|
||||||
|
src++;
|
||||||
|
goto up_one;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy up the next '/' and erase all '/' */
|
||||||
|
while ((c = *src++) != '\0' && c != '/')
|
||||||
|
*dst++ = c;
|
||||||
|
|
||||||
|
if (c == '/')
|
||||||
|
{
|
||||||
|
*dst++ = '/';
|
||||||
|
while (c == '/')
|
||||||
|
c = *src++;
|
||||||
|
|
||||||
|
src--;
|
||||||
|
}
|
||||||
|
else if (!c)
|
||||||
|
break;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
|
||||||
|
up_one:
|
||||||
|
/* keep the topmost root directory */
|
||||||
|
if (dst - dst0 != 1 || dst[-1] != '/')
|
||||||
|
{
|
||||||
|
dst--;
|
||||||
|
|
||||||
|
if (dst < dst0)
|
||||||
|
{
|
||||||
|
rt_free(fullpath);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (dst0 < dst && dst[-1] != '/')
|
||||||
|
dst--;
|
||||||
|
}
|
||||||
|
|
||||||
|
*dst = '\0';
|
||||||
|
|
||||||
|
/* remove '/' in the end of path if exist */
|
||||||
|
dst--;
|
||||||
|
if ((dst != fullpath) && (*dst == '/'))
|
||||||
|
*dst = '\0';
|
||||||
|
|
||||||
|
/* final check fullpath is not empty, for the special path of lwext "/.." */
|
||||||
|
if ('\0' == fullpath[0])
|
||||||
|
{
|
||||||
|
fullpath[0] = '/';
|
||||||
|
fullpath[1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return fullpath;
|
||||||
|
}
|
||||||
|
RTM_EXPORT(dfs_normalize_path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will get the file descriptor table of current process.
|
||||||
|
*/
|
||||||
|
struct dfs_fdtable *dfs_fdtable_get(void)
|
||||||
|
{
|
||||||
|
struct dfs_fdtable *fdt;
|
||||||
|
#ifdef RT_USING_SMART
|
||||||
|
struct rt_lwp *lwp;
|
||||||
|
|
||||||
|
lwp = (struct rt_lwp *)rt_thread_self()->lwp;
|
||||||
|
if (lwp)
|
||||||
|
fdt = &lwp->fdt;
|
||||||
|
else
|
||||||
|
fdt = &_fdtab;
|
||||||
|
#else
|
||||||
|
fdt = &_fdtab;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return fdt;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RT_USING_SMART
|
||||||
|
struct dfs_fdtable *dfs_fdtable_get_pid(int pid)
|
||||||
|
{
|
||||||
|
struct rt_lwp *lwp = RT_NULL;
|
||||||
|
struct dfs_fdtable *fdt = RT_NULL;
|
||||||
|
|
||||||
|
lwp = lwp_from_pid(pid);
|
||||||
|
if (lwp)
|
||||||
|
{
|
||||||
|
fdt = &lwp->fdt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fdt;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct dfs_fdtable *dfs_fdtable_get_global(void)
|
||||||
|
{
|
||||||
|
return &_fdtab;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RT_USING_FINSH
|
||||||
|
int list_fd(void)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
struct dfs_fdtable *fd_table;
|
||||||
|
|
||||||
|
fd_table = dfs_fdtable_get();
|
||||||
|
if (!fd_table) return -1;
|
||||||
|
|
||||||
|
dfs_lock();
|
||||||
|
|
||||||
|
rt_kprintf("fd type ref magic path\n");
|
||||||
|
rt_kprintf("-- ------ --- ----- ------\n");
|
||||||
|
for (index = 0; index < (int)fd_table->maxfd; index++)
|
||||||
|
{
|
||||||
|
struct dfs_file *fd = fd_table->fds[index];
|
||||||
|
|
||||||
|
if (fd && fd->vnode->fops)
|
||||||
|
{
|
||||||
|
rt_kprintf("%2d ", index);
|
||||||
|
if (fd->vnode->type == FT_DIRECTORY) rt_kprintf("%-7.7s ", "dir");
|
||||||
|
else if (fd->vnode->type == FT_REGULAR) rt_kprintf("%-7.7s ", "file");
|
||||||
|
else if (fd->vnode->type == FT_SOCKET) rt_kprintf("%-7.7s ", "socket");
|
||||||
|
else if (fd->vnode->type == FT_USER) rt_kprintf("%-7.7s ", "user");
|
||||||
|
else if (fd->vnode->type == FT_DEVICE) rt_kprintf("%-7.7s ", "device");
|
||||||
|
else rt_kprintf("%-8.8s ", "unknown");
|
||||||
|
rt_kprintf("%3d ", fd->vnode->ref_count);
|
||||||
|
rt_kprintf("%04x ", fd->magic);
|
||||||
|
if (fd->vnode->path)
|
||||||
|
{
|
||||||
|
rt_kprintf("%s\n", fd->vnode->path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_kprintf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dfs_unlock();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RT_USING_SMART
|
||||||
|
static int lsofp(int pid)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
struct dfs_fdtable *fd_table = RT_NULL;
|
||||||
|
|
||||||
|
if (pid == (-1))
|
||||||
|
{
|
||||||
|
fd_table = dfs_fdtable_get();
|
||||||
|
if (!fd_table) return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fd_table = dfs_fdtable_get_pid(pid);
|
||||||
|
if (!fd_table)
|
||||||
|
{
|
||||||
|
rt_kprintf("PID %s is not a applet(lwp)\n", pid);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_kprintf("--- -- ------ ------ ----- ---------- ---------- ---------- ------\n");
|
||||||
|
|
||||||
|
rt_enter_critical();
|
||||||
|
for (index = 0; index < (int)fd_table->maxfd; index++)
|
||||||
|
{
|
||||||
|
struct dfs_file *fd = fd_table->fds[index];
|
||||||
|
|
||||||
|
if (fd && fd->vnode->fops)
|
||||||
|
{
|
||||||
|
if(pid == (-1))
|
||||||
|
{
|
||||||
|
rt_kprintf(" K ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_kprintf("%3d ", pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_kprintf("%2d ", index);
|
||||||
|
if (fd->vnode->type == FT_DIRECTORY) rt_kprintf("%-7.7s ", "dir");
|
||||||
|
else if (fd->vnode->type == FT_REGULAR) rt_kprintf("%-7.7s ", "file");
|
||||||
|
else if (fd->vnode->type == FT_SOCKET) rt_kprintf("%-7.7s ", "socket");
|
||||||
|
else if (fd->vnode->type == FT_USER) rt_kprintf("%-7.7s ", "user");
|
||||||
|
else if (fd->vnode->type == FT_DEVICE) rt_kprintf("%-7.7s ", "device");
|
||||||
|
else rt_kprintf("%-8.8s ", "unknown");
|
||||||
|
rt_kprintf("%6d ", fd->vnode->ref_count);
|
||||||
|
rt_kprintf("%04x 0x%.8x ", fd->magic, (int)(size_t)fd->vnode);
|
||||||
|
|
||||||
|
if(fd->vnode == RT_NULL)
|
||||||
|
{
|
||||||
|
rt_kprintf("0x%.8x 0x%.8x ", (int)0x00000000, (int)(size_t)fd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_kprintf("0x%.8x 0x%.8x ", (int)(size_t)(fd->vnode->data), (int)(size_t)fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd->vnode->path)
|
||||||
|
{
|
||||||
|
rt_kprintf("%s \n", fd->vnode->path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_kprintf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rt_exit_critical();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lsof(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
rt_kprintf("PID fd type fd-ref magic vnode vnode/data addr path \n");
|
||||||
|
|
||||||
|
if (argc == 1)
|
||||||
|
{
|
||||||
|
struct rt_list_node *node, *list;
|
||||||
|
struct lwp_avl_struct *pids = lwp_get_pid_ary();
|
||||||
|
|
||||||
|
lsofp(-1);
|
||||||
|
|
||||||
|
for (int index = 0; index < RT_LWP_MAX_NR; index++)
|
||||||
|
{
|
||||||
|
struct rt_lwp *lwp = (struct rt_lwp *)pids[index].data;
|
||||||
|
|
||||||
|
if (lwp)
|
||||||
|
{
|
||||||
|
list = &lwp->t_grp;
|
||||||
|
for (node = list->next; node != list; node = node->next)
|
||||||
|
{
|
||||||
|
lsofp(lwp_to_pid(lwp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (argc == 3)
|
||||||
|
{
|
||||||
|
if (argv[1][0] == '-' && argv[1][1] == 'p')
|
||||||
|
{
|
||||||
|
int pid = atoi(argv[2]);
|
||||||
|
lsofp(pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
MSH_CMD_EXPORT(lsof, list open files);
|
||||||
|
#endif /* RT_USING_SMART */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/**@}*/
|
||||||
|
|
1094
components/dfs/dfs_v1/src/dfs_file.c
Normal file
1094
components/dfs/dfs_v1/src/dfs_file.c
Normal file
File diff suppressed because it is too large
Load diff
657
components/dfs/dfs_v1/src/dfs_fs.c
Normal file
657
components/dfs/dfs_v1/src/dfs_fs.c
Normal file
|
@ -0,0 +1,657 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2005-02-22 Bernard The first version.
|
||||||
|
* 2010-06-30 Bernard Optimize for RT-Thread RTOS
|
||||||
|
* 2011-03-12 Bernard fix the filesystem lookup issue.
|
||||||
|
* 2017-11-30 Bernard fix the filesystem_operation_table issue.
|
||||||
|
* 2017-12-05 Bernard fix the fs type search issue in mkfs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dfs_fs.h>
|
||||||
|
#include <dfs_file.h>
|
||||||
|
#include "dfs_private.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup FsApi
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will register a file system instance to device file system.
|
||||||
|
*
|
||||||
|
* @param ops the file system instance to be registered.
|
||||||
|
*
|
||||||
|
* @return 0 on successful, -1 on failed.
|
||||||
|
*/
|
||||||
|
int dfs_register(const struct dfs_filesystem_ops *ops)
|
||||||
|
{
|
||||||
|
int ret = RT_EOK;
|
||||||
|
const struct dfs_filesystem_ops **empty = NULL;
|
||||||
|
const struct dfs_filesystem_ops **iter;
|
||||||
|
|
||||||
|
/* lock filesystem */
|
||||||
|
dfs_lock();
|
||||||
|
/* check if this filesystem was already registered */
|
||||||
|
for (iter = &filesystem_operation_table[0];
|
||||||
|
iter < &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX]; iter ++)
|
||||||
|
{
|
||||||
|
/* find out an empty filesystem type entry */
|
||||||
|
if (*iter == NULL)
|
||||||
|
(empty == NULL) ? (empty = iter) : 0;
|
||||||
|
else if (strcmp((*iter)->name, ops->name) == 0)
|
||||||
|
{
|
||||||
|
rt_set_errno(-EEXIST);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* save the filesystem's operations */
|
||||||
|
if (empty == NULL)
|
||||||
|
{
|
||||||
|
rt_set_errno(-ENOSPC);
|
||||||
|
LOG_E("There is no space to register this file system (%s).", ops->name);
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
else if (ret == RT_EOK)
|
||||||
|
{
|
||||||
|
*empty = ops;
|
||||||
|
}
|
||||||
|
|
||||||
|
dfs_unlock();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will return the file system mounted on specified path.
|
||||||
|
*
|
||||||
|
* @param path the specified path string.
|
||||||
|
*
|
||||||
|
* @return the found file system or NULL if no file system mounted on
|
||||||
|
* specified path
|
||||||
|
*/
|
||||||
|
struct dfs_filesystem *dfs_filesystem_lookup(const char *path)
|
||||||
|
{
|
||||||
|
struct dfs_filesystem *iter;
|
||||||
|
struct dfs_filesystem *fs = NULL;
|
||||||
|
uint32_t fspath, prefixlen;
|
||||||
|
|
||||||
|
prefixlen = 0;
|
||||||
|
|
||||||
|
RT_ASSERT(path);
|
||||||
|
|
||||||
|
/* lock filesystem */
|
||||||
|
dfs_lock();
|
||||||
|
|
||||||
|
/* lookup it in the filesystem table */
|
||||||
|
for (iter = &filesystem_table[0];
|
||||||
|
iter < &filesystem_table[DFS_FILESYSTEMS_MAX]; iter++)
|
||||||
|
{
|
||||||
|
if ((iter->path == NULL) || (iter->ops == NULL))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fspath = strlen(iter->path);
|
||||||
|
if ((fspath < prefixlen)
|
||||||
|
|| (strncmp(iter->path, path, fspath) != 0))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* check next path separator */
|
||||||
|
if (fspath > 1 && (strlen(path) > fspath) && (path[fspath] != '/'))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fs = iter;
|
||||||
|
prefixlen = fspath;
|
||||||
|
}
|
||||||
|
|
||||||
|
dfs_unlock();
|
||||||
|
|
||||||
|
return fs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will return the mounted path for specified device.
|
||||||
|
*
|
||||||
|
* @param device the device object which is mounted.
|
||||||
|
*
|
||||||
|
* @return the mounted path or NULL if none device mounted.
|
||||||
|
*/
|
||||||
|
const char *dfs_filesystem_get_mounted_path(struct rt_device *device)
|
||||||
|
{
|
||||||
|
const char *path = NULL;
|
||||||
|
struct dfs_filesystem *iter;
|
||||||
|
|
||||||
|
dfs_lock();
|
||||||
|
for (iter = &filesystem_table[0];
|
||||||
|
iter < &filesystem_table[DFS_FILESYSTEMS_MAX]; iter++)
|
||||||
|
{
|
||||||
|
/* find the mounted device */
|
||||||
|
if (iter->ops == NULL) continue;
|
||||||
|
else if (iter->dev_id == device)
|
||||||
|
{
|
||||||
|
path = iter->path;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* release filesystem_table lock */
|
||||||
|
dfs_unlock();
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will fetch the partition table on specified buffer.
|
||||||
|
*
|
||||||
|
* @param part the returned partition structure.
|
||||||
|
* @param buf the buffer contains partition table.
|
||||||
|
* @param pindex the index of partition table to fetch.
|
||||||
|
*
|
||||||
|
* @return RT_EOK on successful or -RT_ERROR on failed.
|
||||||
|
*/
|
||||||
|
int dfs_filesystem_get_partition(struct dfs_partition *part,
|
||||||
|
uint8_t *buf,
|
||||||
|
uint32_t pindex)
|
||||||
|
{
|
||||||
|
#define DPT_ADDRESS 0x1be /* device partition offset in Boot Sector */
|
||||||
|
#define DPT_ITEM_SIZE 16 /* partition item size */
|
||||||
|
|
||||||
|
uint8_t *dpt;
|
||||||
|
uint8_t type;
|
||||||
|
|
||||||
|
RT_ASSERT(part != NULL);
|
||||||
|
RT_ASSERT(buf != NULL);
|
||||||
|
|
||||||
|
dpt = buf + DPT_ADDRESS + pindex * DPT_ITEM_SIZE;
|
||||||
|
|
||||||
|
/* check if it is a valid partition table */
|
||||||
|
if ((*dpt != 0x80) && (*dpt != 0x00))
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
/* get partition type */
|
||||||
|
type = *(dpt + 4);
|
||||||
|
if (type == 0)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
/* set partition information
|
||||||
|
* size is the number of 512-Byte */
|
||||||
|
part->type = type;
|
||||||
|
part->offset = *(dpt + 8) | *(dpt + 9) << 8 | *(dpt + 10) << 16 | *(dpt + 11) << 24;
|
||||||
|
part->size = *(dpt + 12) | *(dpt + 13) << 8 | *(dpt + 14) << 16 | *(dpt + 15) << 24;
|
||||||
|
|
||||||
|
rt_kprintf("found part[%d], begin: %d, size: ",
|
||||||
|
pindex, part->offset * 512);
|
||||||
|
if ((part->size >> 11) == 0)
|
||||||
|
rt_kprintf("%d%s", part->size >> 1, "KB\n"); /* KB */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned int part_size;
|
||||||
|
part_size = part->size >> 11; /* MB */
|
||||||
|
if ((part_size >> 10) == 0)
|
||||||
|
rt_kprintf("%d.%d%s", part_size, (part->size >> 1) & 0x3FF, "MB\n");
|
||||||
|
else
|
||||||
|
rt_kprintf("%d.%d%s", part_size >> 10, part_size & 0x3FF, "GB\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will mount a file system on a specified path.
|
||||||
|
*
|
||||||
|
* @param device_name the name of device which includes a file system.
|
||||||
|
* @param path the path to mount a file system
|
||||||
|
* @param filesystemtype the file system type
|
||||||
|
* @param rwflag the read/write etc. flag.
|
||||||
|
* @param data the private data(parameter) for this file system.
|
||||||
|
*
|
||||||
|
* @return 0 on successful or -1 on failed.
|
||||||
|
*/
|
||||||
|
int dfs_mount(const char *device_name,
|
||||||
|
const char *path,
|
||||||
|
const char *filesystemtype,
|
||||||
|
unsigned long rwflag,
|
||||||
|
const void *data)
|
||||||
|
{
|
||||||
|
const struct dfs_filesystem_ops **ops;
|
||||||
|
struct dfs_filesystem *iter;
|
||||||
|
struct dfs_filesystem *fs = NULL;
|
||||||
|
char *fullpath = NULL;
|
||||||
|
rt_device_t dev_id;
|
||||||
|
|
||||||
|
/* open specific device */
|
||||||
|
if (device_name == NULL)
|
||||||
|
{
|
||||||
|
/* which is a non-device filesystem mount */
|
||||||
|
dev_id = NULL;
|
||||||
|
}
|
||||||
|
else if ((dev_id = rt_device_find(device_name)) == NULL)
|
||||||
|
{
|
||||||
|
/* no this device */
|
||||||
|
rt_set_errno(-ENODEV);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find out the specific filesystem */
|
||||||
|
dfs_lock();
|
||||||
|
|
||||||
|
for (ops = &filesystem_operation_table[0];
|
||||||
|
ops < &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX]; ops++)
|
||||||
|
if ((*ops != NULL) && (strncmp((*ops)->name, filesystemtype, strlen((*ops)->name)) == 0))
|
||||||
|
break;
|
||||||
|
|
||||||
|
dfs_unlock();
|
||||||
|
|
||||||
|
if (ops == &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX])
|
||||||
|
{
|
||||||
|
/* can't find filesystem */
|
||||||
|
rt_set_errno(-ENODEV);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if there is mount implementation */
|
||||||
|
if ((*ops == NULL) || ((*ops)->mount == NULL))
|
||||||
|
{
|
||||||
|
rt_set_errno(-ENOSYS);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make full path for special file */
|
||||||
|
fullpath = dfs_normalize_path(NULL, path);
|
||||||
|
if (fullpath == NULL) /* not an abstract path */
|
||||||
|
{
|
||||||
|
rt_set_errno(-ENOTDIR);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if the path exists or not, raw APIs call, fixme */
|
||||||
|
if ((strcmp(fullpath, "/") != 0) && (strcmp(fullpath, "/dev") != 0))
|
||||||
|
{
|
||||||
|
struct dfs_file fd;
|
||||||
|
|
||||||
|
fd_init(&fd);
|
||||||
|
if (dfs_file_open(&fd, fullpath, O_RDONLY | O_DIRECTORY) < 0)
|
||||||
|
{
|
||||||
|
rt_free(fullpath);
|
||||||
|
rt_set_errno(-ENOTDIR);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
dfs_file_close(&fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check whether the file system mounted or not in the filesystem table
|
||||||
|
* if it is unmounted yet, find out an empty entry */
|
||||||
|
dfs_lock();
|
||||||
|
|
||||||
|
for (iter = &filesystem_table[0];
|
||||||
|
iter < &filesystem_table[DFS_FILESYSTEMS_MAX]; iter++)
|
||||||
|
{
|
||||||
|
/* check if it is an empty filesystem table entry? if it is, save fs */
|
||||||
|
if (iter->ops == NULL)
|
||||||
|
(fs == NULL) ? (fs = iter) : 0;
|
||||||
|
/* check if the PATH is mounted */
|
||||||
|
else if (strcmp(iter->path, path) == 0)
|
||||||
|
{
|
||||||
|
rt_set_errno(-EINVAL);
|
||||||
|
goto err1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fs == NULL) && (iter == &filesystem_table[DFS_FILESYSTEMS_MAX]))
|
||||||
|
{
|
||||||
|
rt_set_errno(-ENOSPC);
|
||||||
|
LOG_E("There is no space to mount this file system (%s).", filesystemtype);
|
||||||
|
goto err1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* register file system */
|
||||||
|
fs->path = fullpath;
|
||||||
|
fs->ops = *ops;
|
||||||
|
fs->dev_id = dev_id;
|
||||||
|
/* For UFS, record the real filesystem name */
|
||||||
|
fs->data = (void *) filesystemtype;
|
||||||
|
|
||||||
|
/* release filesystem_table lock */
|
||||||
|
dfs_unlock();
|
||||||
|
|
||||||
|
/* open device, but do not check the status of device */
|
||||||
|
if (dev_id != NULL)
|
||||||
|
{
|
||||||
|
if (rt_device_open(fs->dev_id,
|
||||||
|
RT_DEVICE_OFLAG_RDWR) != RT_EOK)
|
||||||
|
{
|
||||||
|
/* The underlying device has error, clear the entry. */
|
||||||
|
dfs_lock();
|
||||||
|
rt_memset(fs, 0, sizeof(struct dfs_filesystem));
|
||||||
|
|
||||||
|
goto err1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* call mount of this filesystem */
|
||||||
|
if ((*ops)->mount(fs, rwflag, data) < 0)
|
||||||
|
{
|
||||||
|
/* close device */
|
||||||
|
if (dev_id != NULL)
|
||||||
|
rt_device_close(fs->dev_id);
|
||||||
|
|
||||||
|
/* mount failed */
|
||||||
|
dfs_lock();
|
||||||
|
/* clear filesystem table entry */
|
||||||
|
rt_memset(fs, 0, sizeof(struct dfs_filesystem));
|
||||||
|
|
||||||
|
goto err1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err1:
|
||||||
|
dfs_unlock();
|
||||||
|
rt_free(fullpath);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will unmount a file system on specified path.
|
||||||
|
*
|
||||||
|
* @param specialfile the specified path which mounted a file system.
|
||||||
|
*
|
||||||
|
* @return 0 on successful or -1 on failed.
|
||||||
|
*/
|
||||||
|
int dfs_unmount(const char *specialfile)
|
||||||
|
{
|
||||||
|
char *fullpath;
|
||||||
|
struct dfs_filesystem *iter;
|
||||||
|
struct dfs_filesystem *fs = NULL;
|
||||||
|
|
||||||
|
fullpath = dfs_normalize_path(NULL, specialfile);
|
||||||
|
if (fullpath == NULL)
|
||||||
|
{
|
||||||
|
rt_set_errno(-ENOTDIR);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lock filesystem */
|
||||||
|
dfs_lock();
|
||||||
|
|
||||||
|
for (iter = &filesystem_table[0];
|
||||||
|
iter < &filesystem_table[DFS_FILESYSTEMS_MAX]; iter++)
|
||||||
|
{
|
||||||
|
/* check if the PATH is mounted */
|
||||||
|
if ((iter->path != NULL) && (strcmp(iter->path, fullpath) == 0))
|
||||||
|
{
|
||||||
|
fs = iter;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs == NULL ||
|
||||||
|
fs->ops->unmount == NULL ||
|
||||||
|
fs->ops->unmount(fs) < 0)
|
||||||
|
{
|
||||||
|
goto err1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* close device, but do not check the status of device */
|
||||||
|
if (fs->dev_id != NULL)
|
||||||
|
rt_device_close(fs->dev_id);
|
||||||
|
|
||||||
|
if (fs->path != NULL)
|
||||||
|
rt_free(fs->path);
|
||||||
|
|
||||||
|
/* clear this filesystem table entry */
|
||||||
|
rt_memset(fs, 0, sizeof(struct dfs_filesystem));
|
||||||
|
|
||||||
|
dfs_unlock();
|
||||||
|
rt_free(fullpath);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err1:
|
||||||
|
dfs_unlock();
|
||||||
|
rt_free(fullpath);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* make a file system on the special device
|
||||||
|
*
|
||||||
|
* @param fs_name the file system name
|
||||||
|
* @param device_name the special device name
|
||||||
|
*
|
||||||
|
* @return 0 on successful, otherwise failed.
|
||||||
|
*/
|
||||||
|
int dfs_mkfs(const char *fs_name, const char *device_name)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
rt_device_t dev_id = NULL;
|
||||||
|
|
||||||
|
/* check device name, and it should not be NULL */
|
||||||
|
if (device_name != NULL)
|
||||||
|
dev_id = rt_device_find(device_name);
|
||||||
|
|
||||||
|
if (dev_id == NULL)
|
||||||
|
{
|
||||||
|
rt_set_errno(-ENODEV);
|
||||||
|
LOG_E("Device (%s) was not found", device_name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lock file system */
|
||||||
|
dfs_lock();
|
||||||
|
/* find the file system operations */
|
||||||
|
for (index = 0; index < DFS_FILESYSTEM_TYPES_MAX; index ++)
|
||||||
|
{
|
||||||
|
if (filesystem_operation_table[index] != NULL &&
|
||||||
|
strncmp(filesystem_operation_table[index]->name, fs_name,
|
||||||
|
strlen(filesystem_operation_table[index]->name)) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dfs_unlock();
|
||||||
|
|
||||||
|
if (index < DFS_FILESYSTEM_TYPES_MAX)
|
||||||
|
{
|
||||||
|
/* find file system operation */
|
||||||
|
const struct dfs_filesystem_ops *ops = filesystem_operation_table[index];
|
||||||
|
if (ops->mkfs == NULL)
|
||||||
|
{
|
||||||
|
LOG_E("The file system (%s) mkfs function was not implement", fs_name);
|
||||||
|
rt_set_errno(-ENOSYS);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ops->mkfs(dev_id, fs_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_E("File system (%s) was not found.", fs_name);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will return the information about a mounted file system.
|
||||||
|
*
|
||||||
|
* @param path the path which mounted file system.
|
||||||
|
* @param buffer the buffer to save the returned information.
|
||||||
|
*
|
||||||
|
* @return 0 on successful, others on failed.
|
||||||
|
*/
|
||||||
|
int dfs_statfs(const char *path, struct statfs *buffer)
|
||||||
|
{
|
||||||
|
struct dfs_filesystem *fs;
|
||||||
|
|
||||||
|
fs = dfs_filesystem_lookup(path);
|
||||||
|
if (fs != NULL)
|
||||||
|
{
|
||||||
|
if (fs->ops->statfs != NULL)
|
||||||
|
return fs->ops->statfs(fs, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_set_errno(-ENOSYS);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RT_USING_DFS_MNTTABLE
|
||||||
|
int dfs_mount_table(void)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (mount_table[index].path == NULL) break;
|
||||||
|
|
||||||
|
if (dfs_mount(mount_table[index].device_name,
|
||||||
|
mount_table[index].path,
|
||||||
|
mount_table[index].filesystemtype,
|
||||||
|
mount_table[index].rwflag,
|
||||||
|
mount_table[index].data) != 0)
|
||||||
|
{
|
||||||
|
LOG_E("mount fs[%s] on %s failed.\n", mount_table[index].filesystemtype,
|
||||||
|
mount_table[index].path);
|
||||||
|
return -RT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
index ++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
INIT_ENV_EXPORT(dfs_mount_table);
|
||||||
|
|
||||||
|
int dfs_mount_device(rt_device_t dev)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
if(dev == RT_NULL) {
|
||||||
|
rt_kprintf("the device is NULL to be mounted.\n");
|
||||||
|
return -RT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (mount_table[index].path == NULL) break;
|
||||||
|
|
||||||
|
if(strcmp(mount_table[index].device_name, dev->parent.name) == 0) {
|
||||||
|
if (dfs_mount(mount_table[index].device_name,
|
||||||
|
mount_table[index].path,
|
||||||
|
mount_table[index].filesystemtype,
|
||||||
|
mount_table[index].rwflag,
|
||||||
|
mount_table[index].data) != 0)
|
||||||
|
{
|
||||||
|
LOG_E("mount fs[%s] device[%s] to %s failed.\n", mount_table[index].filesystemtype, dev->parent.name,
|
||||||
|
mount_table[index].path);
|
||||||
|
return -RT_ERROR;
|
||||||
|
} else {
|
||||||
|
LOG_D("mount fs[%s] device[%s] to %s ok.\n", mount_table[index].filesystemtype, dev->parent.name,
|
||||||
|
mount_table[index].path);
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
index ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_kprintf("can't find device:%s to be mounted.\n", dev->parent.name);
|
||||||
|
return -RT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_unmount_device(rt_device_t dev)
|
||||||
|
{
|
||||||
|
struct dfs_filesystem *iter;
|
||||||
|
struct dfs_filesystem *fs = NULL;
|
||||||
|
|
||||||
|
/* lock filesystem */
|
||||||
|
dfs_lock();
|
||||||
|
|
||||||
|
for (iter = &filesystem_table[0];
|
||||||
|
iter < &filesystem_table[DFS_FILESYSTEMS_MAX]; iter++)
|
||||||
|
{
|
||||||
|
/* check if the PATH is mounted */
|
||||||
|
if (strcmp(iter->dev_id->parent.name, dev->parent.name) == 0)
|
||||||
|
{
|
||||||
|
fs = iter;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs == NULL ||
|
||||||
|
fs->ops->unmount == NULL ||
|
||||||
|
fs->ops->unmount(fs) < 0)
|
||||||
|
{
|
||||||
|
goto err1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* close device, but do not check the status of device */
|
||||||
|
if (fs->dev_id != NULL)
|
||||||
|
rt_device_close(fs->dev_id);
|
||||||
|
|
||||||
|
if (fs->path != NULL)
|
||||||
|
rt_free(fs->path);
|
||||||
|
|
||||||
|
/* clear this filesystem table entry */
|
||||||
|
rt_memset(fs, 0, sizeof(struct dfs_filesystem));
|
||||||
|
|
||||||
|
dfs_unlock();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err1:
|
||||||
|
dfs_unlock();
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RT_USING_FINSH
|
||||||
|
#include <finsh.h>
|
||||||
|
void mkfs(const char *fs_name, const char *device_name)
|
||||||
|
{
|
||||||
|
dfs_mkfs(fs_name, device_name);
|
||||||
|
}
|
||||||
|
FINSH_FUNCTION_EXPORT(mkfs, make a file system);
|
||||||
|
|
||||||
|
int df(const char *path)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
int minor = 0;
|
||||||
|
long long cap;
|
||||||
|
struct statfs buffer;
|
||||||
|
|
||||||
|
int unit_index = 0;
|
||||||
|
char *unit_str[] = {"KB", "MB", "GB"};
|
||||||
|
|
||||||
|
result = dfs_statfs(path ? path : NULL, &buffer);
|
||||||
|
if (result != 0)
|
||||||
|
{
|
||||||
|
if (rt_get_errno() == -ENOSYS)
|
||||||
|
rt_kprintf("The function is not implemented.\n");
|
||||||
|
else
|
||||||
|
rt_kprintf("statfs failed: errno=%d.\n", rt_get_errno());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cap = ((long long)buffer.f_bsize) * ((long long)buffer.f_bfree) / 1024LL;
|
||||||
|
for (unit_index = 0; unit_index < 2; unit_index ++)
|
||||||
|
{
|
||||||
|
if (cap < 1024) break;
|
||||||
|
|
||||||
|
minor = (cap % 1024) * 10 / 1024; /* only one decimal point */
|
||||||
|
cap = cap / 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_kprintf("disk free: %d.%d %s [ %d block, %d bytes per block ]\n",
|
||||||
|
(unsigned long)cap, minor, unit_str[unit_index], buffer.f_bfree, buffer.f_bsize);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
FINSH_FUNCTION_EXPORT(df, get disk free);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**@}*/
|
1026
components/dfs/dfs_v1/src/dfs_posix.c
Normal file
1026
components/dfs/dfs_v1/src/dfs_posix.c
Normal file
File diff suppressed because it is too large
Load diff
35
components/dfs/dfs_v2/Kconfig
Normal file
35
components/dfs/dfs_v2/Kconfig
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
if RT_USING_DFS_V2
|
||||||
|
config RT_USING_DFS_DEVFS
|
||||||
|
bool "Using devfs for device objects"
|
||||||
|
default y
|
||||||
|
|
||||||
|
config RT_USING_DFS_ROMFS
|
||||||
|
bool "Enable ReadOnly file system on flash"
|
||||||
|
default n
|
||||||
|
|
||||||
|
config RT_USING_DFS_CROMFS
|
||||||
|
bool "Enable ReadOnly compressed file system on flash"
|
||||||
|
default n
|
||||||
|
# select PKG_USING_ZLIB
|
||||||
|
|
||||||
|
config RT_USING_DFS_RAMFS
|
||||||
|
bool "Enable RAM file system"
|
||||||
|
select RT_USING_MEMHEAP
|
||||||
|
default n
|
||||||
|
|
||||||
|
config RT_USING_DFS_TMPFS
|
||||||
|
bool "Enable TMP file system"
|
||||||
|
default n
|
||||||
|
|
||||||
|
config RT_USING_DFS_NFS
|
||||||
|
bool "Using NFS v3 client file system"
|
||||||
|
depends on RT_USING_LWIP
|
||||||
|
default n
|
||||||
|
|
||||||
|
if RT_USING_DFS_NFS
|
||||||
|
config RT_NFS_HOST_EXPORT
|
||||||
|
string "NFSv3 host export"
|
||||||
|
default "192.168.1.5:/"
|
||||||
|
endif
|
||||||
|
|
||||||
|
endif
|
25
components/dfs/dfs_v2/SConscript
Normal file
25
components/dfs/dfs_v2/SConscript
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
from building import *
|
||||||
|
import os
|
||||||
|
|
||||||
|
# The set of source files associated with this SConscript file.
|
||||||
|
src = []
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
CPPPATH = [cwd + "/include"]
|
||||||
|
group = []
|
||||||
|
|
||||||
|
if GetDepend('RT_USING_DFS') and GetDepend('RT_USING_DFS_V2'):
|
||||||
|
src = ['src/dfs.c', 'src/dfs_file.c', 'src/dfs_fs.c']
|
||||||
|
|
||||||
|
if GetDepend('DFS_USING_POSIX'):
|
||||||
|
src += ['src/dfs_posix.c']
|
||||||
|
|
||||||
|
group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS'], CPPPATH = CPPPATH)
|
||||||
|
|
||||||
|
# search in the file system implementation
|
||||||
|
list = os.listdir(cwd)
|
||||||
|
|
||||||
|
for item in list:
|
||||||
|
if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
|
||||||
|
group = group + SConscript(os.path.join(item, 'SConscript'))
|
||||||
|
|
||||||
|
Return('group')
|
4
components/dfs/dfs_v2/filesystems/.ignore_format.yml
Normal file
4
components/dfs/dfs_v2/filesystems/.ignore_format.yml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# files format check exclude path, please follow the instructions below to modify;
|
||||||
|
|
||||||
|
dir_path:
|
||||||
|
- elmfat
|
15
components/dfs/dfs_v2/filesystems/SConscript
Normal file
15
components/dfs/dfs_v2/filesystems/SConscript
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# RT-Thread building script for bridge
|
||||||
|
|
||||||
|
import os
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
objs = []
|
||||||
|
list = os.listdir(cwd)
|
||||||
|
|
||||||
|
for d in list:
|
||||||
|
path = os.path.join(cwd, d)
|
||||||
|
if os.path.isfile(os.path.join(path, 'SConscript')):
|
||||||
|
objs = objs + SConscript(os.path.join(d, 'SConscript'))
|
||||||
|
|
||||||
|
Return('objs')
|
11
components/dfs/dfs_v2/filesystems/cromfs/SConscript
Normal file
11
components/dfs/dfs_v2/filesystems/cromfs/SConscript
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# RT-Thread building script for component
|
||||||
|
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
src = Glob('*.c')
|
||||||
|
CPPPATH = [cwd]
|
||||||
|
|
||||||
|
group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS','RT_USING_DFS_CROMFS'], CPPPATH = CPPPATH)
|
||||||
|
|
||||||
|
Return('group')
|
1170
components/dfs/dfs_v2/filesystems/cromfs/dfs_cromfs.c
Normal file
1170
components/dfs/dfs_v2/filesystems/cromfs/dfs_cromfs.c
Normal file
File diff suppressed because it is too large
Load diff
16
components/dfs/dfs_v2/filesystems/cromfs/dfs_cromfs.h
Normal file
16
components/dfs/dfs_v2/filesystems/cromfs/dfs_cromfs.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2020, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2020/08/21 ShaoJinchun firset version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DFS_CROMFS_H__
|
||||||
|
#define __DFS_CROMFS_H__
|
||||||
|
|
||||||
|
int dfs_cromfs_init(void);
|
||||||
|
|
||||||
|
#endif /*__DFS_CROMFS_H__*/
|
11
components/dfs/dfs_v2/filesystems/devfs/SConscript
Normal file
11
components/dfs/dfs_v2/filesystems/devfs/SConscript
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# RT-Thread building script for component
|
||||||
|
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
src = Glob('*.c')
|
||||||
|
CPPPATH = [cwd]
|
||||||
|
|
||||||
|
group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS', 'RT_USING_DFS_DEVFS'], CPPPATH = CPPPATH)
|
||||||
|
|
||||||
|
Return('group')
|
416
components/dfs/dfs_v2/filesystems/devfs/devfs.c
Normal file
416
components/dfs/dfs_v2/filesystems/devfs/devfs.c
Normal file
|
@ -0,0 +1,416 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2018-02-11 Bernard Ignore O_CREAT flag in open.
|
||||||
|
*/
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rtdevice.h>
|
||||||
|
|
||||||
|
#include <dfs.h>
|
||||||
|
#include <dfs_fs.h>
|
||||||
|
#include <dfs_file.h>
|
||||||
|
|
||||||
|
#include "devfs.h"
|
||||||
|
|
||||||
|
struct device_dirent
|
||||||
|
{
|
||||||
|
rt_device_t *devices;
|
||||||
|
rt_uint16_t read_index;
|
||||||
|
rt_uint16_t device_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
int dfs_device_fs_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data)
|
||||||
|
{
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_device_fs_statfs(struct dfs_filesystem *fs, struct statfs *buf)
|
||||||
|
{
|
||||||
|
buf->f_bsize = 512;
|
||||||
|
buf->f_blocks = 2048 * 64; // 64M
|
||||||
|
buf->f_bfree = buf->f_blocks;
|
||||||
|
buf->f_bavail = buf->f_bfree;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_device_fs_ioctl(struct dfs_file *file, int cmd, void *args)
|
||||||
|
{
|
||||||
|
rt_err_t result;
|
||||||
|
rt_device_t dev_id;
|
||||||
|
|
||||||
|
RT_ASSERT(file != RT_NULL);
|
||||||
|
|
||||||
|
/* get device handler */
|
||||||
|
dev_id = (rt_device_t)file->vnode->data;
|
||||||
|
RT_ASSERT(dev_id != RT_NULL);
|
||||||
|
|
||||||
|
if ((file->vnode->path[0] == '/') && (file->vnode->path[1] == '\0'))
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
|
||||||
|
/* close device handler */
|
||||||
|
result = rt_device_control(dev_id, cmd, args);
|
||||||
|
if (result == RT_EOK)
|
||||||
|
return RT_EOK;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_device_fs_read(struct dfs_file *file, void *buf, size_t count)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
rt_device_t dev_id;
|
||||||
|
|
||||||
|
RT_ASSERT(file != RT_NULL);
|
||||||
|
|
||||||
|
/* get device handler */
|
||||||
|
dev_id = (rt_device_t)file->vnode->data;
|
||||||
|
RT_ASSERT(dev_id != RT_NULL);
|
||||||
|
|
||||||
|
if ((file->vnode->path[0] == '/') && (file->vnode->path[1] == '\0'))
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
|
||||||
|
/* read device data */
|
||||||
|
result = rt_device_read(dev_id, file->pos, buf, count);
|
||||||
|
file->pos += result;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_device_fs_write(struct dfs_file *file, const void *buf, size_t count)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
rt_device_t dev_id;
|
||||||
|
|
||||||
|
RT_ASSERT(file != RT_NULL);
|
||||||
|
|
||||||
|
/* get device handler */
|
||||||
|
dev_id = (rt_device_t)file->vnode->data;
|
||||||
|
RT_ASSERT(dev_id != RT_NULL);
|
||||||
|
|
||||||
|
if ((file->vnode->path[0] == '/') && (file->vnode->path[1] == '\0'))
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
|
||||||
|
/* read device data */
|
||||||
|
result = rt_device_write(dev_id, file->pos, buf, count);
|
||||||
|
file->pos += result;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_device_fs_close(struct dfs_file *file)
|
||||||
|
{
|
||||||
|
rt_err_t result;
|
||||||
|
rt_device_t dev_id;
|
||||||
|
|
||||||
|
RT_ASSERT(file != RT_NULL);
|
||||||
|
RT_ASSERT(file->vnode->ref_count > 0);
|
||||||
|
|
||||||
|
if (file->vnode->ref_count > 1)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file->vnode->type == FT_DIRECTORY && (file->vnode->path[0] == '/') && (file->vnode->path[1] == '\0'))
|
||||||
|
{
|
||||||
|
struct device_dirent *root_dirent;
|
||||||
|
|
||||||
|
root_dirent = (struct device_dirent *)file->vnode->data;
|
||||||
|
RT_ASSERT(root_dirent != RT_NULL);
|
||||||
|
|
||||||
|
/* release dirent */
|
||||||
|
rt_free(root_dirent);
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get device handler */
|
||||||
|
dev_id = (rt_device_t)file->vnode->data;
|
||||||
|
RT_ASSERT(dev_id != RT_NULL);
|
||||||
|
|
||||||
|
/* close device handler */
|
||||||
|
result = rt_device_close(dev_id);
|
||||||
|
if (result == RT_EOK)
|
||||||
|
{
|
||||||
|
file->vnode->data = RT_NULL;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_device_fs_open(struct dfs_file *file)
|
||||||
|
{
|
||||||
|
rt_err_t result;
|
||||||
|
rt_device_t device;
|
||||||
|
|
||||||
|
RT_ASSERT(file->vnode->ref_count > 0);
|
||||||
|
if (file->vnode->ref_count > 1)
|
||||||
|
{
|
||||||
|
file->pos = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* open root directory */
|
||||||
|
if ((file->vnode->path[0] == '/') && (file->vnode->path[1] == '\0') &&
|
||||||
|
(file->flags & O_DIRECTORY))
|
||||||
|
{
|
||||||
|
struct rt_object *object;
|
||||||
|
struct rt_list_node *node;
|
||||||
|
struct rt_object_information *information;
|
||||||
|
struct device_dirent *root_dirent;
|
||||||
|
rt_uint32_t count = 0;
|
||||||
|
|
||||||
|
/* lock scheduler */
|
||||||
|
rt_enter_critical();
|
||||||
|
|
||||||
|
/* traverse device object */
|
||||||
|
information = rt_object_get_information(RT_Object_Class_Device);
|
||||||
|
RT_ASSERT(information != RT_NULL);
|
||||||
|
for (node = information->object_list.next; node != &(information->object_list); node = node->next)
|
||||||
|
{
|
||||||
|
count ++;
|
||||||
|
}
|
||||||
|
rt_exit_critical();
|
||||||
|
|
||||||
|
root_dirent = (struct device_dirent *)rt_malloc(sizeof(struct device_dirent) +
|
||||||
|
count * sizeof(rt_device_t));
|
||||||
|
if (root_dirent != RT_NULL)
|
||||||
|
{
|
||||||
|
/* lock scheduler */
|
||||||
|
rt_enter_critical();
|
||||||
|
|
||||||
|
root_dirent->devices = (rt_device_t *)(root_dirent + 1);
|
||||||
|
root_dirent->read_index = 0;
|
||||||
|
root_dirent->device_count = count;
|
||||||
|
count = 0;
|
||||||
|
/* get all device node */
|
||||||
|
for (node = information->object_list.next; node != &(information->object_list); node = node->next)
|
||||||
|
{
|
||||||
|
/* avoid memory write through */
|
||||||
|
if (count == root_dirent->device_count)
|
||||||
|
{
|
||||||
|
rt_kprintf("warning: There are newly added devices that are not displayed!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
object = rt_list_entry(node, struct rt_object, list);
|
||||||
|
root_dirent->devices[count] = (rt_device_t)object;
|
||||||
|
count ++;
|
||||||
|
}
|
||||||
|
rt_exit_critical();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set data */
|
||||||
|
file->vnode->data = root_dirent;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
#ifdef RT_USING_DEV_BUS
|
||||||
|
else if (file->flags & O_CREAT)
|
||||||
|
{
|
||||||
|
if (!(file->flags & O_DIRECTORY))
|
||||||
|
{
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
/* regester bus device */
|
||||||
|
if (rt_device_bus_create(&file->vnode->path[1], 0) == RT_NULL)
|
||||||
|
{
|
||||||
|
return -EEXIST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
device = rt_device_find(&file->vnode->path[1]);
|
||||||
|
if (device == RT_NULL)
|
||||||
|
{
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RT_USING_POSIX_DEVIO
|
||||||
|
if (device->fops)
|
||||||
|
{
|
||||||
|
/* use device fops */
|
||||||
|
file->vnode->fops = device->fops;
|
||||||
|
file->vnode->data = (void *)device;
|
||||||
|
|
||||||
|
/* use fops */
|
||||||
|
if (file->vnode->fops->open)
|
||||||
|
{
|
||||||
|
result = file->vnode->fops->open(file);
|
||||||
|
if (result == RT_EOK || result == -RT_ENOSYS)
|
||||||
|
{
|
||||||
|
file->vnode->type = FT_DEVICE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif /* RT_USING_POSIX_DEVIO */
|
||||||
|
{
|
||||||
|
result = rt_device_open(device, RT_DEVICE_OFLAG_RDWR);
|
||||||
|
if (result == RT_EOK || result == -RT_ENOSYS)
|
||||||
|
{
|
||||||
|
file->vnode->data = device;
|
||||||
|
file->vnode->type = FT_DEVICE;
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file->vnode->data = RT_NULL;
|
||||||
|
/* open device failed. */
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_device_fs_unlink(struct dfs_filesystem *fs, const char *path)
|
||||||
|
{
|
||||||
|
#ifdef RT_USING_DEV_BUS
|
||||||
|
rt_device_t dev_id;
|
||||||
|
|
||||||
|
dev_id = rt_device_find(&path[1]);
|
||||||
|
if (dev_id == RT_NULL)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (dev_id->type != RT_Device_Class_Bus)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
rt_device_bus_destroy(dev_id);
|
||||||
|
#endif
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_device_fs_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
|
||||||
|
{
|
||||||
|
/* stat root directory */
|
||||||
|
if ((path[0] == '/') && (path[1] == '\0'))
|
||||||
|
{
|
||||||
|
st->st_dev = 0;
|
||||||
|
|
||||||
|
st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
|
||||||
|
S_IWUSR | S_IWGRP | S_IWOTH;
|
||||||
|
st->st_mode &= ~S_IFREG;
|
||||||
|
st->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
||||||
|
|
||||||
|
st->st_size = 0;
|
||||||
|
st->st_mtime = 0;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_device_t dev_id;
|
||||||
|
|
||||||
|
dev_id = rt_device_find(&path[1]);
|
||||||
|
if (dev_id != RT_NULL)
|
||||||
|
{
|
||||||
|
st->st_dev = 0;
|
||||||
|
|
||||||
|
st->st_mode = S_IRUSR | S_IRGRP | S_IROTH |
|
||||||
|
S_IWUSR | S_IWGRP | S_IWOTH;
|
||||||
|
|
||||||
|
if (dev_id->type == RT_Device_Class_Char)
|
||||||
|
st->st_mode |= S_IFCHR;
|
||||||
|
else if (dev_id->type == RT_Device_Class_Block)
|
||||||
|
st->st_mode |= S_IFBLK;
|
||||||
|
else if (dev_id->type == RT_Device_Class_Pipe)
|
||||||
|
st->st_mode |= S_IFIFO;
|
||||||
|
else if (dev_id->type == RT_Device_Class_Bus)
|
||||||
|
st->st_mode |= S_IFDIR;
|
||||||
|
else
|
||||||
|
st->st_mode |= S_IFREG;
|
||||||
|
|
||||||
|
st->st_size = 0;
|
||||||
|
st->st_mtime = 0;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_device_fs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count)
|
||||||
|
{
|
||||||
|
rt_uint32_t index;
|
||||||
|
rt_object_t object;
|
||||||
|
struct dirent *d;
|
||||||
|
struct device_dirent *root_dirent;
|
||||||
|
|
||||||
|
root_dirent = (struct device_dirent *)file->vnode->data;
|
||||||
|
RT_ASSERT(root_dirent != RT_NULL);
|
||||||
|
|
||||||
|
/* make integer count */
|
||||||
|
count = (count / sizeof(struct dirent));
|
||||||
|
if (count == 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
for (index = 0; index < count && index + root_dirent->read_index < root_dirent->device_count;
|
||||||
|
index ++)
|
||||||
|
{
|
||||||
|
object = (rt_object_t)root_dirent->devices[root_dirent->read_index + index];
|
||||||
|
|
||||||
|
d = dirp + index;
|
||||||
|
if ((((rt_device_t)object)->type) == RT_Device_Class_Bus)
|
||||||
|
{
|
||||||
|
d->d_type = DT_DIR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d->d_type = DT_REG;
|
||||||
|
}
|
||||||
|
d->d_namlen = RT_NAME_MAX;
|
||||||
|
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
|
||||||
|
rt_strncpy(d->d_name, object->name, RT_NAME_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
root_dirent->read_index += index;
|
||||||
|
|
||||||
|
return index * sizeof(struct dirent);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dfs_device_fs_poll(struct dfs_file *fd, struct rt_pollreq *req)
|
||||||
|
{
|
||||||
|
int mask = 0;
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dfs_file_ops _device_fops =
|
||||||
|
{
|
||||||
|
dfs_device_fs_open,
|
||||||
|
dfs_device_fs_close,
|
||||||
|
dfs_device_fs_ioctl,
|
||||||
|
dfs_device_fs_read,
|
||||||
|
dfs_device_fs_write,
|
||||||
|
RT_NULL, /* flush */
|
||||||
|
RT_NULL, /* lseek */
|
||||||
|
dfs_device_fs_getdents,
|
||||||
|
dfs_device_fs_poll,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct dfs_filesystem_ops _device_fs =
|
||||||
|
{
|
||||||
|
"devfs",
|
||||||
|
DFS_FS_FLAG_DEFAULT,
|
||||||
|
&_device_fops,
|
||||||
|
dfs_device_fs_mount,
|
||||||
|
RT_NULL, /*unmount*/
|
||||||
|
RT_NULL, /*mkfs*/
|
||||||
|
dfs_device_fs_statfs,
|
||||||
|
dfs_device_fs_unlink,
|
||||||
|
dfs_device_fs_stat,
|
||||||
|
RT_NULL, /*rename*/
|
||||||
|
};
|
||||||
|
|
||||||
|
int devfs_init(void)
|
||||||
|
{
|
||||||
|
/* register device file system */
|
||||||
|
dfs_register(&_device_fs);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
17
components/dfs/dfs_v2/filesystems/devfs/devfs.h
Normal file
17
components/dfs/dfs_v2/filesystems/devfs/devfs.h
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DEVICE_FS_H__
|
||||||
|
#define __DEVICE_FS_H__
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
int devfs_init(void);
|
||||||
|
|
||||||
|
#endif
|
10
components/dfs/dfs_v2/filesystems/elmfat/.ignore_format.yml
Normal file
10
components/dfs/dfs_v2/filesystems/elmfat/.ignore_format.yml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# files format check exclude path, please follow the instructions below to modify;
|
||||||
|
# If you need to exclude an entire folder, add the folder path in dir_path;
|
||||||
|
# If you need to exclude a file, add the path to the file in file_path.
|
||||||
|
|
||||||
|
file_path:
|
||||||
|
- diskio.h
|
||||||
|
- ff.c
|
||||||
|
- ff.h
|
||||||
|
- ffconf.h
|
||||||
|
- ffunicode.c
|
359
components/dfs/dfs_v2/filesystems/elmfat/00history.txt
Normal file
359
components/dfs/dfs_v2/filesystems/elmfat/00history.txt
Normal file
|
@ -0,0 +1,359 @@
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
Revision history of FatFs module
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
R0.00 (February 26, 2006)
|
||||||
|
|
||||||
|
Prototype.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.01 (April 29, 2006)
|
||||||
|
|
||||||
|
The first release.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.02 (June 01, 2006)
|
||||||
|
|
||||||
|
Added FAT12 support.
|
||||||
|
Removed unbuffered mode.
|
||||||
|
Fixed a problem on small (<32M) partition.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.02a (June 10, 2006)
|
||||||
|
|
||||||
|
Added a configuration option (_FS_MINIMUM).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.03 (September 22, 2006)
|
||||||
|
|
||||||
|
Added f_rename().
|
||||||
|
Changed option _FS_MINIMUM to _FS_MINIMIZE.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.03a (December 11, 2006)
|
||||||
|
|
||||||
|
Improved cluster scan algorithm to write files fast.
|
||||||
|
Fixed f_mkdir() creates incorrect directory on FAT32.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.04 (February 04, 2007)
|
||||||
|
|
||||||
|
Added f_mkfs().
|
||||||
|
Supported multiple drive system.
|
||||||
|
Changed some interfaces for multiple drive system.
|
||||||
|
Changed f_mountdrv() to f_mount().
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.04a (April 01, 2007)
|
||||||
|
|
||||||
|
Supported multiple partitions on a physical drive.
|
||||||
|
Added a capability of extending file size to f_lseek().
|
||||||
|
Added minimization level 3.
|
||||||
|
Fixed an endian sensitive code in f_mkfs().
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.04b (May 05, 2007)
|
||||||
|
|
||||||
|
Added a configuration option _USE_NTFLAG.
|
||||||
|
Added FSINFO support.
|
||||||
|
Fixed DBCS name can result FR_INVALID_NAME.
|
||||||
|
Fixed short seek (<= csize) collapses the file object.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.05 (August 25, 2007)
|
||||||
|
|
||||||
|
Changed arguments of f_read(), f_write() and f_mkfs().
|
||||||
|
Fixed f_mkfs() on FAT32 creates incorrect FSINFO.
|
||||||
|
Fixed f_mkdir() on FAT32 creates incorrect directory.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.05a (February 03, 2008)
|
||||||
|
|
||||||
|
Added f_truncate() and f_utime().
|
||||||
|
Fixed off by one error at FAT sub-type determination.
|
||||||
|
Fixed btr in f_read() can be mistruncated.
|
||||||
|
Fixed cached sector is not flushed when create and close without write.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.06 (April 01, 2008)
|
||||||
|
|
||||||
|
Added fputc(), fputs(), fprintf() and fgets().
|
||||||
|
Improved performance of f_lseek() on moving to the same or following cluster.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.07 (April 01, 2009)
|
||||||
|
|
||||||
|
Merged Tiny-FatFs as a configuration option. (_FS_TINY)
|
||||||
|
Added long file name feature. (_USE_LFN)
|
||||||
|
Added multiple code page feature. (_CODE_PAGE)
|
||||||
|
Added re-entrancy for multitask operation. (_FS_REENTRANT)
|
||||||
|
Added auto cluster size selection to f_mkfs().
|
||||||
|
Added rewind option to f_readdir().
|
||||||
|
Changed result code of critical errors.
|
||||||
|
Renamed string functions to avoid name collision.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.07a (April 14, 2009)
|
||||||
|
|
||||||
|
Septemberarated out OS dependent code on reentrant cfg.
|
||||||
|
Added multiple sector size feature.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.07c (June 21, 2009)
|
||||||
|
|
||||||
|
Fixed f_unlink() can return FR_OK on error.
|
||||||
|
Fixed wrong cache control in f_lseek().
|
||||||
|
Added relative path feature.
|
||||||
|
Added f_chdir() and f_chdrive().
|
||||||
|
Added proper case conversion to extended character.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.07e (November 03, 2009)
|
||||||
|
|
||||||
|
Septemberarated out configuration options from ff.h to ffconf.h.
|
||||||
|
Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH.
|
||||||
|
Fixed name matching error on the 13 character boundary.
|
||||||
|
Added a configuration option, _LFN_UNICODE.
|
||||||
|
Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.08 (May 15, 2010)
|
||||||
|
|
||||||
|
Added a memory configuration option. (_USE_LFN = 3)
|
||||||
|
Added file lock feature. (_FS_SHARE)
|
||||||
|
Added fast seek feature. (_USE_FASTSEEK)
|
||||||
|
Changed some types on the API, XCHAR->TCHAR.
|
||||||
|
Changed .fname in the FILINFO structure on Unicode cfg.
|
||||||
|
String functions support UTF-8 encoding files on Unicode cfg.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.08a (August 16, 2010)
|
||||||
|
|
||||||
|
Added f_getcwd(). (_FS_RPATH = 2)
|
||||||
|
Added sector erase feature. (_USE_ERASE)
|
||||||
|
Moved file lock semaphore table from fs object to the bss.
|
||||||
|
Fixed f_mkfs() creates wrong FAT32 volume.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.08b (January 15, 2011)
|
||||||
|
|
||||||
|
Fast seek feature is also applied to f_read() and f_write().
|
||||||
|
f_lseek() reports required table size on creating CLMP.
|
||||||
|
Extended format syntax of f_printf().
|
||||||
|
Ignores duplicated directory separators in given path name.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.09 (September 06, 2011)
|
||||||
|
|
||||||
|
f_mkfs() supports multiple partition to complete the multiple partition feature.
|
||||||
|
Added f_fdisk().
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.09a (August 27, 2012)
|
||||||
|
|
||||||
|
Changed f_open() and f_opendir() reject null object pointer to avoid crash.
|
||||||
|
Changed option name _FS_SHARE to _FS_LOCK.
|
||||||
|
Fixed assertion failure due to OS/2 EA on FAT12/16 volume.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.09b (January 24, 2013)
|
||||||
|
|
||||||
|
Added f_setlabel() and f_getlabel().
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.10 (October 02, 2013)
|
||||||
|
|
||||||
|
Added selection of character encoding on the file. (_STRF_ENCODE)
|
||||||
|
Added f_closedir().
|
||||||
|
Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
|
||||||
|
Added forced mount feature with changes of f_mount().
|
||||||
|
Improved behavior of volume auto detection.
|
||||||
|
Improved write throughput of f_puts() and f_printf().
|
||||||
|
Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
|
||||||
|
Fixed f_write() can be truncated when the file size is close to 4GB.
|
||||||
|
Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect value on error.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.10a (January 15, 2014)
|
||||||
|
|
||||||
|
Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
|
||||||
|
Added a configuration option of minimum sector size. (_MIN_SS)
|
||||||
|
2nd argument of f_rename() can have a drive number and it will be ignored.
|
||||||
|
Fixed f_mount() with forced mount fails when drive number is >= 1. (appeared at R0.10)
|
||||||
|
Fixed f_close() invalidates the file object without volume lock.
|
||||||
|
Fixed f_closedir() returns but the volume lock is left acquired. (appeared at R0.10)
|
||||||
|
Fixed creation of an entry with LFN fails on too many SFN collisions. (appeared at R0.07)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.10b (May 19, 2014)
|
||||||
|
|
||||||
|
Fixed a hard error in the disk I/O layer can collapse the directory entry.
|
||||||
|
Fixed LFN entry is not deleted when delete/rename an object with lossy converted SFN. (appeared at R0.07)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.10c (November 09, 2014)
|
||||||
|
|
||||||
|
Added a configuration option for the platforms without RTC. (_FS_NORTC)
|
||||||
|
Changed option name _USE_ERASE to _USE_TRIM.
|
||||||
|
Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). (appeared at R0.09b)
|
||||||
|
Fixed a potential problem of FAT access that can appear on disk error.
|
||||||
|
Fixed null pointer dereference on attempting to delete the root direcotry. (appeared at R0.08)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.11 (February 09, 2015)
|
||||||
|
|
||||||
|
Added f_findfirst(), f_findnext() and f_findclose(). (_USE_FIND)
|
||||||
|
Fixed f_unlink() does not remove cluster chain of the file. (appeared at R0.10c)
|
||||||
|
Fixed _FS_NORTC option does not work properly. (appeared at R0.10c)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.11a (September 05, 2015)
|
||||||
|
|
||||||
|
Fixed wrong media change can lead a deadlock at thread-safe configuration.
|
||||||
|
Added code page 771, 860, 861, 863, 864, 865 and 869. (_CODE_PAGE)
|
||||||
|
Removed some code pages actually not exist on the standard systems. (_CODE_PAGE)
|
||||||
|
Fixed errors in the case conversion teble of code page 437 and 850 (ff.c).
|
||||||
|
Fixed errors in the case conversion teble of Unicode (cc*.c).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.12 (April 12, 2016)
|
||||||
|
|
||||||
|
Added support for exFAT file system. (_FS_EXFAT)
|
||||||
|
Added f_expand(). (_USE_EXPAND)
|
||||||
|
Changed some members in FINFO structure and behavior of f_readdir().
|
||||||
|
Added an option _USE_CHMOD.
|
||||||
|
Removed an option _WORD_ACCESS.
|
||||||
|
Fixed errors in the case conversion table of Unicode (cc*.c).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.12a (July 10, 2016)
|
||||||
|
|
||||||
|
Added support for creating exFAT volume with some changes of f_mkfs().
|
||||||
|
Added a file open method FA_OPEN_APPEND. An f_lseek() following f_open() is no longer needed.
|
||||||
|
f_forward() is available regardless of _FS_TINY.
|
||||||
|
Fixed f_mkfs() creates wrong volume. (appeared at R0.12)
|
||||||
|
Fixed wrong memory read in create_name(). (appeared at R0.12)
|
||||||
|
Fixed compilation fails at some configurations, _USE_FASTSEEK and _USE_FORWARD.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.12b (September 04, 2016)
|
||||||
|
|
||||||
|
Made f_rename() be able to rename objects with the same name but case.
|
||||||
|
Fixed an error in the case conversion teble of code page 866. (ff.c)
|
||||||
|
Fixed writing data is truncated at the file offset 4GiB on the exFAT volume. (appeared at R0.12)
|
||||||
|
Fixed creating a file in the root directory of exFAT volume can fail. (appeared at R0.12)
|
||||||
|
Fixed f_mkfs() creating exFAT volume with too small cluster size can collapse unallocated memory. (appeared at R0.12)
|
||||||
|
Fixed wrong object name can be returned when read directory at Unicode cfg. (appeared at R0.12)
|
||||||
|
Fixed large file allocation/removing on the exFAT volume collapses allocation bitmap. (appeared at R0.12)
|
||||||
|
Fixed some internal errors in f_expand() and f_lseek(). (appeared at R0.12)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.12c (March 04, 2017)
|
||||||
|
|
||||||
|
Improved write throughput at the fragmented file on the exFAT volume.
|
||||||
|
Made memory usage for exFAT be able to be reduced as decreasing _MAX_LFN.
|
||||||
|
Fixed successive f_getfree() can return wrong count on the FAT12/16 volume. (appeared at R0.12)
|
||||||
|
Fixed configuration option _VOLUMES cannot be set 10. (appeared at R0.10c)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.13 (May 21, 2017)
|
||||||
|
|
||||||
|
Changed heading character of configuration keywords "_" to "FF_".
|
||||||
|
Removed ASCII-only configuration, FF_CODE_PAGE = 1. Use FF_CODE_PAGE = 437 instead.
|
||||||
|
Added f_setcp(), run-time code page configuration. (FF_CODE_PAGE = 0)
|
||||||
|
Improved cluster allocation time on stretch a deep buried cluster chain.
|
||||||
|
Improved processing time of f_mkdir() with large cluster size by using FF_USE_LFN = 3.
|
||||||
|
Improved NoFatChain flag of the fragmented file to be set after it is truncated and got contiguous.
|
||||||
|
Fixed archive attribute is left not set when a file on the exFAT volume is renamed. (appeared at R0.12)
|
||||||
|
Fixed exFAT FAT entry can be collapsed when write or lseek operation to the existing file is done. (appeared at R0.12c)
|
||||||
|
Fixed creating a file can fail when a new cluster allocation to the exFAT directory occures. (appeared at R0.12c)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.13a (October 14, 2017)
|
||||||
|
|
||||||
|
Added support for UTF-8 encoding on the API. (FF_LFN_UNICODE = 2)
|
||||||
|
Added options for file name output buffer. (FF_LFN_BUF, FF_SFN_BUF).
|
||||||
|
Added dynamic memory allocation option for working buffer of f_mkfs() and f_fdisk().
|
||||||
|
Fixed f_fdisk() and f_mkfs() create the partition table with wrong CHS parameters. (appeared at R0.09)
|
||||||
|
Fixed f_unlink() can cause lost clusters at fragmented file on the exFAT volume. (appeared at R0.12c)
|
||||||
|
Fixed f_setlabel() rejects some valid characters for exFAT volume. (appeared at R0.12)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.13b (April 07, 2018)
|
||||||
|
|
||||||
|
Added support for UTF-32 encoding on the API. (FF_LFN_UNICODE = 3)
|
||||||
|
Added support for Unix style volume ID. (FF_STR_VOLUME_ID = 2)
|
||||||
|
Fixed accesing any object on the exFAT root directory beyond the cluster boundary can fail. (appeared at R0.12c)
|
||||||
|
Fixed f_setlabel() does not reject some invalid characters. (appeared at R0.09b)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.13c (October 14, 2018)
|
||||||
|
Supported stdint.h for C99 and later. (integer.h was included in ff.h)
|
||||||
|
Fixed reading a directory gets infinite loop when the last directory entry is not empty. (appeared at R0.12)
|
||||||
|
Fixed creating a sub-directory in the fragmented sub-directory on the exFAT volume collapses FAT chain of the parent directory. (appeared at R0.12)
|
||||||
|
Fixed f_getcwd() cause output buffer overrun when the buffer has a valid drive number. (appeared at R0.13b)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.14 (October 14, 2019)
|
||||||
|
Added support for 64-bit LBA and GUID partition table (FF_LBA64 = 1)
|
||||||
|
Changed some API functions, f_mkfs() and f_fdisk().
|
||||||
|
Fixed f_open() function cannot find the file with file name in length of FF_MAX_LFN characters.
|
||||||
|
Fixed f_readdir() function cannot retrieve long file names in length of FF_MAX_LFN - 1 characters.
|
||||||
|
Fixed f_readdir() function returns file names with wrong case conversion. (appeared at R0.12)
|
||||||
|
Fixed f_mkfs() function can fail to create exFAT volume in the second partition. (appeared at R0.12)
|
||||||
|
|
||||||
|
|
||||||
|
R0.14a (December 5, 2020)
|
||||||
|
Limited number of recursive calls in f_findnext().
|
||||||
|
Fixed old floppy disks formatted with MS-DOS 2.x and 3.x cannot be mounted.
|
||||||
|
Fixed some compiler warnings.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.14b (April 17, 2021)
|
||||||
|
Made FatFs uses standard library <string.h> for copy, compare and search instead of built-in string functions.
|
||||||
|
Added support for long long integer and floating point to f_printf(). (FF_STRF_LLI and FF_STRF_FP)
|
||||||
|
Made path name parser ignore the terminating separator to allow "dir/".
|
||||||
|
Improved the compatibility in Unix style path name feature.
|
||||||
|
Fixed the file gets dead-locked when f_open() failed with some conditions. (appeared at R0.12a)
|
||||||
|
Fixed f_mkfs() can create wrong exFAT volume due to a timing dependent error. (appeared at R0.12)
|
||||||
|
Fixed code page 855 cannot be set by f_setcp().
|
||||||
|
Fixed some compiler warnings.
|
||||||
|
|
||||||
|
|
21
components/dfs/dfs_v2/filesystems/elmfat/00readme.txt
Normal file
21
components/dfs/dfs_v2/filesystems/elmfat/00readme.txt
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
FatFs Module Source Files R0.14b
|
||||||
|
|
||||||
|
|
||||||
|
FILES
|
||||||
|
|
||||||
|
00readme.txt This file.
|
||||||
|
00history.txt Revision history.
|
||||||
|
ff.c FatFs module.
|
||||||
|
ffconf.h Configuration file of FatFs module.
|
||||||
|
ff.h Common include file for FatFs and application module.
|
||||||
|
diskio.h Common include file for FatFs and disk I/O module.
|
||||||
|
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
|
||||||
|
ffunicode.c Optional Unicode utility functions.
|
||||||
|
ffsystem.c An example of optional O/S related functions.
|
||||||
|
|
||||||
|
|
||||||
|
Low level disk I/O module is not included in this archive because the FatFs
|
||||||
|
module is only a generic file system layer and it does not depend on any specific
|
||||||
|
storage device. You need to provide a low level disk I/O module written to
|
||||||
|
control the storage device that attached to the target system.
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue