OTG配置为USB盘之二
在前面一节中,描述了otg配置U盘时涉及到的知识点,本篇用统一的脚本完成。
目标
将3588开发板子配置为一个U盘。
配置文件和脚本
配置文件
说明:
1)USB_FUNCS是将开发板配置为什么类型的设备,例如u盘,配置ums等等。
2)UMS_FILE 即对应的具体存储设备,本文就着重讲解此处的应用。
存储设备可以是
a. 一个文件,里面在内存或者磁盘上创建一个img文件。
b. 一个分区
#!/bin/sh# The env variables below can be overridden# option: adb acm hid mtp ntb rndis uac1 uac2 ums uvc
#export USB_FUNCS="adb"
export USB_FUNCS="ums"#export UMS_FILE=/userdata/ums_shared.img
#export UMS_FILE=/dev/mmcblk0p7
export UMS_FILE=/dev/sda5
#export UMS_SIZE=1024M
export UMS_SIZE=7G
export UMS_FSTYPE=ntfs
export UMS_MOUNT=0
export UMS_MOUNTPOINT=/mnt/ums
export UMS_RO=0
设置u盘脚本
脚本运行 usbdevice start等参数
#!/bin/sh # Uncomment below to see more logs
# set -x# Load default env variables from profiles
. /etc/profileLOG_FILE=/tmp/usbdevice.log
USB_FUNCS_FILE=/tmp/.usbdevicealias usb_enable='touch $USB_FUNCS_FILE'
alias usb_disable='rm -f $USB_FUNCS_FILE'
alias usb_is_enabled='[ -f $USB_FUNCS_FILE ]'
alias usb_set_started='echo $USB_FUNCS > $USB_FUNCS_FILE'
usb_get_started()
{usb_is_enabled || return 0cat $USB_FUNCS_FILE
}CONFIGFS_DIR=/sys/kernel/config
USB_GROUP=rockchip
USB_STRINGS_ATTR=strings/0x409
USB_GADGET_DIR=$CONFIGFS_DIR/usb_gadget/$USB_GROUP
USB_GADGET_STRINGS_DIR=$USB_GADGET_DIR/$USB_STRINGS_ATTR
USB_FUNCTIONS_DIR=$USB_GADGET_DIR/functions
USB_CONFIGS_DIR=$USB_GADGET_DIR/configs/b.1
USB_CONFIGS_STRINGS_DIR=$USB_CONFIGS_DIR/$USB_STRINGS_ATTR# Make sure that we own this session (pid equals sid)
if ! ps x -o cmd,pid,sid | grep -wq "$$$"; thensetsid $0 $@exit $?
fi# ---- helper functions
usb_msg()
{logger -t $(basename $0) "[$$]: $@"echo "[$(date +"%F %T")] $@"
}usb_pid()
{case $1 inums) echo 0x0000;;mtp) echo 0x0001;;uvc) echo 0x0005;;adb) echo 0x0006;;adb_mtp) echo 0x0011;;adb_ums) echo 0x0018;;adb_uvc) echo 0x0015;;ntb_uvc) echo 0x0017;;acm) echo 0x1005;;*) echo 0x0019;;esac
}usb_instances()
{for func in $@; doVAR=$(echo $func | tr 'a-z' 'A-Z')_INSTANCESeval echo "\${$VAR:-$func.gs0}"done
}usb_run_stage()
{for f in $1_pre_$2_hook $1_$2 $1_post_$2_hook; dotype $f >/dev/null 2>/dev/null || continueusb_msg "Run stage: $f"eval $f || breakdone
}usb_wait_files()
{for i in `seq 200`;dofuser -s $@ 2>/dev/null && breaksleep .01done
}usb_release_files()
{for i in `seq 200`;dofuser -s -k $@ 2>/dev/null || breaksleep .01done
}# usage: usb_mount <src> <mountpoint> <options>
usb_mount()
{mkdir -p $2mountpoint -q $2 || mount $@
}usb_umount()
{mountpoint -q $1 || return 0usb_release_files -m $1umount $1
}usb_symlink()
{mkdir -p $1[ -e $2 ] || ln -s $1 $2
}usb_try_symlink()
{usb_symlink $@ &>/dev/null || true
}usb_write()
{if echo "x$1" | grep -q "^x-"; thenOPTS=$1shiftfiFILE=$1shiftif [ -r $FILE ] && [ "$(cat $FILE)" = "$@" ]; thenreturn 0fiecho $OPTS "$@" > $FILE
}usb_try_write()
{usb_write $@ &>/dev/null || true
}usb_start_daemon()
{NAME=$(echo $1 | sed "s#^[^ ]*/\([^ ]*\).*#\1#")TAG_FILE=/tmp/.usb_$NAME# Enable spawntouch $TAG_FILE# Already started[ -z "$(usb_get_started)" ] || return 0# Start and spawn background daemon{exec 3<&-cd /while usb_is_enabled; do# Don't spawn after stopped[ ! -f $TAG_FILE ] ||start-stop-daemon -Sqx $@ || truesleep .5done}&
}usb_stop_daemon()
{NAME=$(echo $1 | sed "s#^[^ ]*/\([^ ]*\).*#\1#")TAG_FILE=/tmp/.usb_$NAME# Stop and disable spawnrm -f $TAG_FILEstart-stop-daemon -Kqox $@
}usb_load_config()
{USB_CONFIG_FILE=$(find /etc/ -name .usb_config | head -n 1)[ -n "$USB_CONFIG_FILE" -a -r $USB_CONFIG_FILE ] || return 0ums_parse(){grep "\<$1=" $USB_CONFIG_FILE | cut -d'=' -f2}UMS_FILE=$(ums_parse ums_block)UMS_SIZE=$(ums_parse ums_block_size || echo 0)MUMS_FSTYPE=$(ums_parse ums_block_type)UMS_MOUNT=$([ "$(ums_parse ums_block_auto_mount)" != on ]; echo $?)UMS_RO=$([ "$(ums_parse ums_block_ro)" != on ]; echo $?)USB_FUNCS=$(grep "usb_.*_en" $USB_CONFIG_FILE | cut -d'_' -f2 | xargs)
}# ---- adb
ADB_INSTANCES=${ADB_INSTANCES:-ffs.adb}adb_prepare()
{usb_mount adb /dev/usb-ffs/adb -o uid=2000,gid=2000 -t functionfsusb_start_daemon /usr/bin/adbdusb_wait_files -m /dev/usb-ffs/adb
}adb_stop()
{usb_stop_daemon /usr/bin/adbd
}# ---- ntb
NTB_INSTANCES=${NTB_INSTANCES:-ffs.ntb}ntb_prepare()
{usb_mount ntb /dev/usb-ffs/ntb -o uid=2000,gid=2000 -t functionfs
}# ---- uac1
uac1_prepare()
{for f in $(find . -name "*_feature_unit"); doecho 1 >$fdone
}# ---- uac2
uac2_prepare()
{uac1_prepare
}# ---- mtp
mtp_prepare()
{echo "MTP" > os_desc/interface.MTP/compatible_idecho 1 > $USB_GADGET_DIR/os_desc/use
}mtp_start()
{usb_start_daemon /usr/bin/mtp-serverusb_wait_files /dev/mtp_usb
}mtp_stop()
{usb_stop_daemon /usr/bin/mtp-serverusb_release_files /dev/mtp_usbecho 0 > $USB_GADGET_DIR/os_desc/use
}# ---- acm
ACM_INSTANCES=${ACM_INSTANCES:-acm.gs6}# ---- rndis
# Nothing special# ---- uvc
UVC_INSTANCES=${UVC_INSTANCES:-uvc.gs6}uvc_add_yuyv()
{WIDTH=$(echo $1 | cut -d'x' -f1)HEIGHT=$(echo $1 | cut -d'x' -f2)DIR=${HEIGHT}p[ ! -d $DIR ] || return 0mkdir -p $DIRecho $WIDTH > $DIR/wWidthecho $HEIGHT > $DIR/wHeightecho 333333 > $DIR/dwDefaultFrameIntervalecho $((WIDTH * HEIGHT * 20)) > $DIR/dwMinBitRateecho $((WIDTH * HEIGHT * 20)) > $DIR/dwMaxBitRateecho $((WIDTH * HEIGHT * 2)) > $DIR/dwMaxVideoFrameBufferSizeecho -e "333333\n666666\n1000000\n2000000" > $DIR/dwFrameInterval
}uvc_add_mjpeg()
{WIDTH=$(echo $1 | cut -d'x' -f1)HEIGHT=$(echo $1 | cut -d'x' -f2)DIR=${HEIGHT}p[ ! -d $DIR ] || return 0mkdir -p $DIRecho $WIDTH > $DIR/wWidthecho $HEIGHT > $DIR/wHeightecho 333333 > $DIR/dwDefaultFrameIntervalecho $((WIDTH * HEIGHT * 20)) > $DIR/dwMinBitRateecho $((WIDTH * HEIGHT * 20)) > $DIR/dwMaxBitRateecho $((WIDTH * HEIGHT * 2)) > $DIR/dwMaxVideoFrameBufferSizeecho -e "333333\n666666\n1000000\n2000000" > $DIR/dwFrameInterval
}uvc_add_h264()
{WIDTH=$(echo $1 | cut -d'x' -f1)HEIGHT=$(echo $1 | cut -d'x' -f2)DIR=${HEIGHT}p[ ! -d $DIR ] || return 0mkdir -p $DIRecho $WIDTH > $DIR/wWidthecho $HEIGHT > $DIR/wHeightecho 333333 > $DIR/dwDefaultFrameIntervalecho $((WIDTH * HEIGHT * 10)) > $DIR/dwMinBitRateecho $((WIDTH * HEIGHT * 10)) > $DIR/dwMaxBitRateecho -e "333333\n666666\n1000000\n2000000" > $DIR/dwFrameInterval
}uvc_support_resolutions()
{case ${1:-yuyv} inyuyv) echo "640x480 1280x720";;mjpeg) echo "640x480 1280x720 1920x1080 2560x1440 2592x1944";;h264) echo "640x480 1280x720 1920x1080";;esac
}uvc_prepare()
{UVC_DIR=$(pwd)usb_symlink $UVC_DIR/control/header/h $UVC_DIR/control/class/fs/husb_symlink $UVC_DIR/control/header/h $UVC_DIR/control/class/ss/husb_symlink $UVC_DIR/streaming/header/h $UVC_DIR/streaming/class/fs/husb_symlink $UVC_DIR/streaming/header/h $UVC_DIR/streaming/class/hs/husb_symlink $UVC_DIR/streaming/header/h $UVC_DIR/streaming/class/ss/hUVC_YUYV_RES=$(uvc_support_resolutions yuyv)if [ -n "$UVC_YUYV_RES" ]; thenusb_try_symlink $UVC_DIR/streaming/uncompressed/u \$UVC_DIR/streaming/header/h/ucd $UVC_DIR/streaming/uncompressed/ufor res in $UVC_YUYV_RES; douvc_add_yuyv $resdonefiUVC_MJPEG_RES=$(uvc_support_resolutions mjpeg)if [ -n "$UVC_MJPEG_RES" ]; thenusb_try_symlink $UVC_DIR/streaming/mjpeg/m \$UVC_DIR/streaming/header/h/mcd $UVC_DIR/streaming/mjpeg/mfor res in $UVC_MJPEG_RES; douvc_add_mjpeg $resdonefiUVC_H264_RES=$(uvc_support_resolutions h264)if [ -n "$UVC_H264_RES" ]; thenusb_try_symlink $UVC_DIR/streaming/framebased/f \$UVC_DIR/streaming/header/h/fcd $UVC_DIR/streaming/framebased/ffor res in $UVC_H264_RES; douvc_add_h264 $resdoneusb_try_write -ne guidFormat "\\x48\\x32\\x36\\x34\\x00\\x00\\x10\\x00\\x80\\x00\\x00\\xaa\\x00\\x38\\x9b\\x71"fi
}# TODO: Start UVC daemon in uvc_start
# TODO: Stop UVC daemon in uvc_stop# ---- hid
HID_INSTANCES=${HID_INSTANCES:-hid.usb0}hid_prepare()
{echo 1 > protocolecho 1 > subclassecho 8 > report_lengthecho -ne "\\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0" \> report_desc
}# ---- ums
UMS_INSTANCES=${UMS_INSTANCES:-mass_storage.0}ums_prepare()
{if [ ! -f $UMS_FILE ]; thenusb_msg "Formating $UMS_FILE($UMS_SIZE) to $UMS_FSTYPE"#truncate -s $UMS_SIZE $UMS_FILE#mkfs.$UMS_FSTYPE -s 4096 -L "mbca19" $UMS_FILE || \# usb_msg "Failed to format $UMS_FILE to $UMS_FSTYPE"fi
}ums_stop()
{echo > lun.0/fileusb_umount $UMS_MOUNTPOINT[ "$UMS_MOUNT" -eq 1 ] || return 0# Try auto fstype firstlyusb_mount $UMS_FILE $UMS_MOUNTPOINT -o async 2>/dev/null || \usb_mount $UMS_FILE $UMS_MOUNTPOINT -o async -t $UMS_FSTYPE
}ums_start()
{echo "current : $(pwd)"case "$USB_STATE" inCONFIGURED)if [ "$(cat lun.0/ro)" != "$UMS_RO" ]; thenecho > lun.0/fileecho $UMS_RO > lun.0/rofiif ! grep -wq $UMS_FILE lun.0/file; thenusb_umount $UMS_MOUNTPOINTecho $UMS_FILE > lun.0/filefi;;DISCONNECTED)ums_stop;;esac
}# ---- global
usb_init()
{usb_msg "Initializing"echo 0x2207 > idVendorecho 0x0310 > bcdDeviceecho 0x0200 > bcdUSBmkdir -p $USB_GADGET_STRINGS_DIRSERIAL=$(grep Serial /proc/cpuinfo | cut -d':' -f2)echo ${SERIAL:-0123456789ABCDEF} > $USB_GADGET_STRINGS_DIR/serialnumberecho $USB_GROUP > $USB_GADGET_STRINGS_DIR/manufacturerecho "rk3xxhjx" > $USB_GADGET_STRINGS_DIR/productmkdir -p $USB_CONFIGS_DIRecho 500 > $USB_CONFIGS_DIR/MaxPowerecho 0x1 > os_desc/b_vendor_codeecho MSFT100 > os_desc/qw_signln -s $USB_CONFIGS_DIR os_desc/mkdir -p $USB_CONFIGS_STRINGS_DIR
}usb_funcs_grep()
{echo $USB_FUNCS | xargs -n 1 | sort | uniq | grep $@ || true
}usb_funcs_sort()
{{for func in $@; dousb_funcs_grep -E $funcdoneusb_funcs_grep -vE $(echo $@ | tr ' ' '|')} | uniq | xargs
}usb_prepare()
{usb_load_config# Allow function/variable overriding[ -d /etc/usbdevice.d ] && . /etc/usbdevice.d/*UMS_FILE=${UMS_FILE:-/userdata/ums_shared.img}UMS_SIZE=${UMS_SIZE:-256M}UMS_FSTYPE=${UMS_FSTYPE:-vfat}UMS_MOUNT=${UMS_MOUNT:-0}UMS_MOUNTPOINT=${UMS_MOUNTPOINT:-/mnt/ums}UMS_RO=${UMS_RO:-0}# Put RNDIS & UAC & UVC at first (required by kernel)USB_FUNCS=$(usb_funcs_sort rndis uac uvc)if [ ! -d $USB_GADGET_DIR ]; thenmountpoint -q $CONFIGFS_DIR || \mount -t configfs none $CONFIGFS_DIRmkdir -p $USB_GADGET_DIRcd $USB_GADGET_DIR# Global initializeusb_run_stage usb initfiUSB_STATE=$(cat /sys/class/android_usb/android0/state)USB_UDC=$(ls /sys/class/udc/ | head -n 1)# Parse started USB functionsOLD_FUNCS=$(usb_get_started)# Stop old USB functions when USB functions changedif [ -n "$OLD_FUNCS" ] && [ "$OLD_FUNCS" != "$USB_FUNCS" ]; thenusb_msg "Functions changed $OLD_FUNCS -> $USB_FUNCS"usb_stopfi
}usb_start()
{usb_msg "Starting functions: $USB_FUNCS"echo $USB_FUNCS | tr ' ' '_' > $USB_CONFIGS_STRINGS_DIR/configurationfor func in $USB_FUNCS; dofor instance in $(usb_instances $func); dousb_msg "Preparing instance: $instance"if ! mkdir -p $USB_FUNCTIONS_DIR/$instance 2>/dev/null; thenusb_msg "Failed to create instance: $instance"continuefiecho "except dir: $USB_FUNCTIONS_DIR/$instance"cd $USB_FUNCTIONS_DIR/$instance &>/dev/null || continuecd $USB_FUNCTIONS_DIR/$instanceecho "start dir : $(pwd)"usb_run_stage $func prepare# Make symlink after prepared (required by UVC)usb_symlink $USB_FUNCTIONS_DIR/$instance \$USB_CONFIGS_DIR/f-$instancedonedoneusb_write $USB_GADGET_DIR/UDC $USB_UDCfor func in $USB_FUNCS; dofor instance in $(usb_instances $func); docd $USB_FUNCTIONS_DIR/$instance &>/dev/null || continueusb_msg "Starting instance: $instance"usb_run_stage $func startdonedone# Store started functionsusb_set_started
}usb_stop()
{if [ -n "$OLD_FUNCS" ]; thenusb_msg "Stopping functions: $OLD_FUNCS"fiusb_write $USB_GADGET_DIR/UDC ""for func in $USB_FUNCS; dofor instance in $(usb_instances $func); docd $USB_FUNCTIONS_DIR/$instance &>/dev/null || continueusb_msg "Stopping instance: $instance"usb_run_stage $func stopdonedonerm -f $USB_CONFIGS_DIR/f-*# Clear functions to avoid stopping them againunset OLD_FUNCS
}usb_restart()
{usb_run_stage usb stopusb_run_stage usb start
}ACTION=${1:-update}
if [ "$ACTION" = update ]; thenusb_is_enabled || exit 0
fi# Lock it
exec 3<$0
flock -x 3echo "Starting $0 ${ACTION}, log saved to $LOG_FILE"# Redirect outputs to log file
exec >>$LOG_FILE 2>&1usb_msg "Handling ${ACTION} request"usb_run_stage usb preparecase "$ACTION" instart|update)usb_enableusb_run_stage usb start;;stop)usb_disableusb_run_stage usb stop;;restart)usb_enableusb_run_stage usb restart;;*)echo "Usage: usbdevice [start|stop|restart|update]" >&2;;
esacusb_msg "Done $ACTION request"
echo# Unlock it
flock -u 3
步骤
以内存为存储介质
创建文件
mount -t tmpfs -o size=4G tmpfs /mnt/mem
并在/mnt/mem 目录下创建 test.img 文件作为 U 盘存储
dd if=/dev/zero of=test.img bs=1M count=2048
这里注意一点:img文件并不能被格式化,则上述U盘脚本中的 如下格式化的部分,需要注释掉,否则有问题。
ums_prepare()
{if [ ! -f $UMS_FILE ]; thenusb_msg "Formating $UMS_FILE($UMS_SIZE) to $UMS_FSTYPE"#truncate -s $UMS_SIZE $UMS_FILE#mkfs.$UMS_FSTYPE -s 4096 -L "mbca19" $UMS_FILE || \# usb_msg "Failed to format $UMS_FILE to $UMS_FSTYPE"fi
}
创建后,在windows下访问时先要将其格式为NTFS等。
以U盘SATA盘等为存储介质
首先格式化为NTFS,然后运行上述脚本进行usb 设备创建。
将开发板插入到windows下可以直接作为U盘使用,不需要格式化等额外操作。
可以实现linux 下面写,而windows读的,满足类似移动硬盘的应用场景。
性能测试
在windows下用 CD 工具压测,环境采用USB3.0的接口(特别要注意线缆的选择,用2.0的线缆是)。
相关文章:

OTG配置为USB盘之二
在前面一节中,描述了otg配置U盘时涉及到的知识点,本篇用统一的脚本完成。 目标 将3588开发板子配置为一个U盘。 配置文件和脚本 配置文件 说明: 1)USB_FUNCS是将开发板配置为什么类型的设备,例如u盘,配置um…...

如何使用 PHP 函数与其他 Web 服务交互?
在 PHP 中,我们可以使用 cURL 或者 file_get_contents 函数与其他 Web 服务进行交互。 使用 cURL 函数 cURL 是一个库,它允许你使用各种类型的协议来发送数据,并从服务器获取数据。 $curl curl_init(‘http://example.com/api’); curl_s…...

.NetCore+vue3上传图片 Multipart body length limit 16384 exceeded.
实现目标。点击图片上传头像 效果图 前端部分图片上传关键代码 <div class"avatar-wrap"><el-imagestyle"width: 154px; height: 154px":src"form.headPic":fit"fit"/></div><div class"upload-box"…...

机器学习如何用于音频分析?
机器学习如何用于音频分析? 一、说明 近十年来,机器学习越来越受欢迎。事实上,它被用于医疗保健、农业和制造业等众多行业。随着技术和计算能力的进步,机器学习有很多潜在的应用正在被创造出来。由于数据以多种格式大量可用&…...

适合程序员在周末阅读的历史书籍:理解人性和世界
一、《人类简史:从动物到上帝》 这本书提供了对人类历史和社会发展的深刻洞察,帮助读者理解人类过去、现在和可能的未来。 《人类简史:从动物到上帝》是以色列历史学家尤瓦尔赫拉利(Yuval Noah Harari)创作的一部极具影…...

探索Mem0:下一代人工智能与机器学习内存管理基础设施(二)Mem0+Ollama 部署运行
探索Mem0:下一代人工智能与机器学习内存管理基础设施(二) Mem 0(发音为“mem-zero”)通过智能记忆层增强AI助手和代理,实现个性化的AI交互。Mem 0会记住用户偏好,适应个人需求,并随着时间的推移不断改进,使其成为客户支持聊天机器人,AI助手和自治系统的理想选择。 …...

C++入门10——stack与queue的使用
目录 1.什么是stack? stack的使用 2.什么是queue? queue的使用 3.priority_queue 3.1 什么是priority_queue? 3.2 priority_queue的使用 1.什么是stack? 在官网中,对stack有这样的介绍: Stacks are a type o…...

詳細解析軟路由與代理爬蟲池-okeyproxy
什麼是軟路由? 軟路由,顧名思義,就是通過軟體實現的路由器功能。與傳統的硬體路由器不同,軟路由通常是基於PC或單板電腦(如樹莓派)運行的路由器軟體。 靈活性高:可以根據需求安裝各種插件和服…...

视频监控管理平台LntonAIServer视频智能分析噪声检测应用场景
在视频监控系统中,噪声问题常常影响到视频画面的清晰度和可用性。噪声可能由多种因素引起,包括但不限于低光环境、摄像机传感器灵敏度过高、编码压缩失真等。LntonAIServer通过引入噪声检测功能,旨在帮助用户及时发现并解决视频流中的噪声问题…...

技术分享-商城篇-用户中心-注销修改(二十三)
前言 上一篇文章技术分享-商城篇-用户中心(二十二)在构建高效、安全的商城用户中心时,确保用户账户的安全性与便捷性至关重要。本文将重点阐述三大核心功能——修改密码、协议授权及注销账户的业务逻辑、设计思路及注意事项,旨在…...

Linux-实用指令
目录 前言 指定运行级别 基本介绍 切换运行级别 指令类 帮助指令 man 获得帮助信息 help指令 文件目录类 pwd指令 ls指令 cd指令 mkdir命令 rmdir指令删除空目录 touch指令 cp指令 rm指令 mv指令 cat指令 more指令 less指令 echo指令 head指令 tail指令…...

【MySQL00】【 杂七杂八】
文章目录 一、前言二、MySQL 文件1. 参数文件2. 日志文件3. 套接字文件4. pid 文件5. 表结构定义文件6. InnoDB 存储引擎文件 二、BTree 索引排序三、InnoDB 关键特性1. 插入缓冲1.1 Insert Buffer 和 Change Buffer1.1 缓冲合并 2. 两次写2. 自适应哈希索引3. 异步IO4. 刷新邻…...

计算机网络 第2章 物理层
文章目录 通信基础基本概念信道的极限容量编码与调制常用的编码方法常用的调制方法 传输介质双绞线同轴电缆光纤以太网对有限传输介质的命名规则无线传输介质物理层接口的特性 物理层设备中继器集线器一些特性 物理层任务:实现相邻节点之间比特(0或1&…...

解决:Module build failed (from ./node_modules/sass-loader/dist/cjs.js)问题
一、问题 Module build failed (from ./node_modules/sass-loader/dist/cjs.js): Error: Cannot find module sass 二、解决方法 1.清除缓存 npm cache clean --force2.重构项目 npm install 3.更新(获取最新的)node-sass和sass-loader依赖包 npm …...

【 html+css 绚丽Loading 】 000041 三才移形三角
前言:哈喽,大家好,今天给大家分享htmlcss 绚丽Loading!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕…...

ASP.NET Core 入门教学十六 防止常见的Web攻击
在ASP.NET Core中,防止常见的Web攻击是非常重要的,以确保应用程序的安全性。以下是一些常见的Web攻击类型及其防范措施: 1. 跨站脚本攻击(XSS) 跨站脚本攻击(XSS)是一种通过在网页中注入恶意脚…...

单刀直入@ComponentScan之 资源加载
欢迎大家入坑,所谓师傅领进坑爬出去靠个人,首先我要说的是这个是上一篇《单刀直入ComponentScan》的姊妹篇哈,接着把没聊透的事说明白,咱不是虎头蛇尾的人。 资源加载是啥意思 scan ,都认识吧,小学词汇连…...

SAPUI5基础知识25 - 聚合绑定(Aggregation Binding)
1. 背景 Aggregation Binding 是 SAPUI5 中的一种数据绑定方式,用于将数据模型中的集合(如数组)绑定到 UI 控件的聚合(如列表项、表格行等)。 常见的场景包括将一个数组绑定到 sap.m.List 的 items 聚合,…...

【Python 千题 —— 算法篇】寻找两个正序数组的中位数
Python 千题持续更新中 …… 脑图地址 👉:⭐https://twilight-fanyi.gitee.io/mind-map/Python千题.html⭐ 题目背景 在处理大规模数据时,我们经常需要对数据进行排序和分析。一个常见问题是如何高效地从两个正序数组中找出它们的中位数。…...

Autoware 定位之初始姿态输入(九)
0. 简介 这一讲按照《Autoware 技术代码解读(三)》梳理的顺序,我们来说一说Autoware中的初始化操作,这个软件包当中完成了ekf_localizer发送初始姿态的包。它接收来自GNSS/用户的粗略估计的初始姿态。将姿态传递给ndt_scan_match…...

C# 自定义传值窗体-适合多参数传值
将子窗体的值回传到父窗体中,或者最简单的需要一个设置参数的对话框,其作用也就是得到其中的参数。下面我们详细介绍实现的过程。 文章目录 一、定义一个事件类二、在参数窗体中定义事件三、订阅事件消息 一、定义一个事件类 首先,我们必须…...

Ubuntu20.04+ros-noetic配置Cartographer
一、概述 因为要配置激光SLAM,Cartographer属于激光雷达SLAM 中比较经典的一款,在学习之前先将其在Ubuntu20.04首先配置出来并成功运行demo。 二、具体操作 (一)概述 使用平台是Windows的wsl2上的Ubuntu20.04子系统,…...

Visual Studio 2022 下载和安装
文章目录 概述一,下载步骤二,安装过程 概述 Visual Studio 提供 AI 增强功能,例如用于上下文感知代码补全的 IntelliSense 和可利用开源代码中的 AI 模式的 IntelliCode。 集成的 GitHub Copilot 提供 AI 支持的代码补全、聊天辅助、调试建议…...

在 Windows 环境下实现免密登录 Linux 服务器
在 Windows 环境下实现免密登录 Linux 服务器 1. 生成 SSH 密钥对2. 手动将公钥上传到服务器方法 1:使用 scp 传输公钥文件方法 2:使用 Windows 内置工具或编辑器手动复制 3. 测试免密登录4. 可能需要的工具 以下是在 Windows 中实现免密登录的步骤&…...

Computer Exercise
每日一练 单选题 在计算机机箱前面板接口插针上( C )表示复位开关。 A.SPK B.PWRLED C.RESET D.HDDLED每台PC机最多可接( B )块IDE硬盘。 A.2 B.4 C.6 D.8( …...

利用Stable Diffusion AI图像模型评估智能车模型算法表现(下篇)
今天小李哥将介绍亚马逊云科技的Jupyter Notebook机器学习托管服务Amazon SageMaker上,通过AI图像生成模型Stable Diffusion Upscale和Depth、向量知识库和LangChain Agent,生成用于AI 智能车模型训练的图像数据集并评估模型表现。 本系列共分为上下两篇…...

音视频入门基础:WAV专题(8)——FFmpeg源码中计算WAV音频文件AVStream的time_base的实现
一、引言 本文讲解FFmpeg源码对WAV音频文件进行解复用(解封装)时,其AVStream的time_base是怎样被计算出来的。 二、FFmpeg源码中计算WAV音频文件AVStream的time_base的实现 从《音视频入门基础:WAV专题(5)…...

springboot中的请求过滤filter与拦截interceptor分析
首先我们要定义一个类,实现标准的过滤器 import lombok.extern.slf4j.Slf4j;import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException;WebFilter("/*") Slf4j public class AuthFilter implements Filter {Overr…...

Node.js入门与生态全解析:包管理与构建工具详解
Node.js入门与生态全解析:包管理与构建工具详解 目录 🎯 包管理 使用 npm 和 yarn:项目依赖管理的利器创建和发布 npm 包:实现模块化与共享 ⚙️ 构建工具 使用 Webpack 和 Babel:高效打包与代码转换配置构建流程&am…...

828华为云征文|华为云Flexus X实例docker部署harbor镜像仓库
828华为云征文|华为云Flexus X实例docker部署harbor镜像仓库 华为云最近正在举办828 B2B企业节,Flexus X实例的促销力度非常大,特别适合那些对算力性能有高要求的小伙伴。如果你有自建MySQL、Redis、Nginx等服务的需求,一定不要错…...