From 05cc1b41a978b8c605540d24bb00aca80562a30b Mon Sep 17 00:00:00 2001 From: taorye Date: Thu, 12 Dec 2024 16:08:02 +0800 Subject: [PATCH 1/3] feat: add support for uvc-gadget and provide a server default --- .../SG200X/overlay/etc/init.d/S03usbdev | 17 +- .../overlay/etc/init.d/uvc-gadget-server.elf | Bin 0 -> 22504 bytes .../SG200X/overlay/etc/init.d/uvc_tool.sh | 256 ++++++++++++++++++ 3 files changed, 271 insertions(+), 2 deletions(-) create mode 100755 buildroot/board/cvitek/SG200X/overlay/etc/init.d/uvc-gadget-server.elf create mode 100755 buildroot/board/cvitek/SG200X/overlay/etc/init.d/uvc_tool.sh diff --git a/buildroot/board/cvitek/SG200X/overlay/etc/init.d/S03usbdev b/buildroot/board/cvitek/SG200X/overlay/etc/init.d/S03usbdev index b492b5c33..27f2cc88f 100755 --- a/buildroot/board/cvitek/SG200X/overlay/etc/init.d/S03usbdev +++ b/buildroot/board/cvitek/SG200X/overlay/etc/init.d/S03usbdev @@ -76,6 +76,13 @@ then echo 'licheervnano' > strings/0x409/product fi mkdir -p configs/c.1 + # uvc + if [ -e /boot/usb.uvc ] + then + /etc/init.d/uvc_tool.sh mount /boot/usb.uvc + /etc/init.d/uvc_tool.sh server + fi + if [ -e /boot/usb.GS0 ] then mkdir -p functions/acm.GS0 @@ -168,6 +175,14 @@ fi if [ "$1" = "stop" ] then + echo '' > /sys/kernel/config/usb_gadget/g0/UDC + echo host > /proc/cviusb/otg_role + # uvc + if [ -e /sys/kernel/config/usb_gadget/g0/configs/c.1/uvc.usb0 ] + then + /etc/init.d/uvc_tool.sh unmount + fi + # rndis if [ -e /sys/kernel/config/usb_gadget/g0/configs/c.1/rndis.usb0 ] then @@ -181,7 +196,5 @@ then unlink /sys/kernel/config/usb_gadget/g0/configs/c.1/ncm.usb0 rmdir /sys/kernel/config/usb_gadget/g0/functions/ncm.usb0 fi - echo '' > /sys/kernel/config/usb_gadget/g0/UDC - echo host > /proc/cviusb/otg_role fi diff --git a/buildroot/board/cvitek/SG200X/overlay/etc/init.d/uvc-gadget-server.elf b/buildroot/board/cvitek/SG200X/overlay/etc/init.d/uvc-gadget-server.elf new file mode 100755 index 0000000000000000000000000000000000000000..993e01f22a48c68f8ee2bef52be6e1ed3ccfe97f GIT binary patch literal 22504 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 Ni1x4Qfw(ue|DV}5?P&l2 literal 0 HcmV?d00001 diff --git a/buildroot/board/cvitek/SG200X/overlay/etc/init.d/uvc_tool.sh b/buildroot/board/cvitek/SG200X/overlay/etc/init.d/uvc_tool.sh new file mode 100755 index 000000000..05323df2a --- /dev/null +++ b/buildroot/board/cvitek/SG200X/overlay/etc/init.d/uvc_tool.sh @@ -0,0 +1,256 @@ +#! /bin/sh + +# 支持的格式,可以通过修改这个变量自定义支持的格式 +# Supported formats, you can customize the list by modifying this variable +supported_formats="yuyv mjpg" + +# 支持的分辨率,可以通过修改这个变量自定义支持的分辨率 +# Supported resolutions, you can customize the list by modifying this variable +supported_resolutions="640x360 1280x720 1920x1080" + + +parse_uvc_config() { + input_file="$1" # 传入的文件路径 / Path to the input file + parsed_data="" # 初始化 parsed_data 为空 / Initialize parsed_data as empty + + # 检查文件是否存在并可读取 / Check if the file exists and is readable + if [ -z "$input_file" ]; then + # 没有提供文件路径 / No input file provided + echo "Warn: No input file provided for config." 1>&2 # 输出到标准错误 / Output to stderr + elif [ ! -f "$input_file" ]; then + # 文件不存在 / File does not exist + echo "Warn: File '$input_file' does not exist." 1>&2 # 输出到标准错误 / Output to stderr + elif [ ! -r "$input_file" ]; then + # 文件不可读取 / File is not readable + echo "Warn: File '$input_file' is not readable." 1>&2 # 输出到标准错误 / Output to stderr + else + # 使用 awk 处理文件内容 / Using awk to process the file content + parsed_data=$(awk -v resolutions="$supported_resolutions" -v formats="$supported_formats" ' + BEGIN { + OFS = " "; + split(resolutions, supported_res, " "); # 将支持的分辨率放入数组 / Split the supported resolutions into an array + split(formats, supported_fmt, " "); # 将支持的格式放入数组 / Split the supported formats into an array + } + /^[^#]/ { # 只处理非 # 开头的行 / Process lines that do not start with # + fmt = $1; + res = $2; + + # 检查格式是否在支持的格式列表中 / Check if the format is in the supported formats list + is_supported_fmt = 0; + for (i in supported_fmt) { + if (fmt == supported_fmt[i]) { + is_supported_fmt = 1; + break; + } + } + if (!is_supported_fmt) { + print "Unsupported format:", fmt > "/dev/stderr"; # 输出不支持的格式到标准错误 / Output unsupported format to stderr + next; + } + + if (res ~ /^[0-9]+x[0-9]+$/) { # 匹配 640x360/1280x720 这种格式 / Match the format like 640x360 or 1280x720 + is_supported_res = 0; + for (i in supported_res) { + if (res == supported_res[i]) { + is_supported_res = 1; + break; + } + } + if (!is_supported_res) { + print "Unsupported resolution:", res > "/dev/stderr"; # 输出不支持的分辨率到标准错误 / Output unsupported resolution to stderr + next; + } + split(res, dims, "x"); # 将 1280x720 按 "x" 分割成宽高 / Split 1280x720 into width and height + w = dims[1]; + h = dims[2]; + } else { + print "Invalid resolution format:", res > "/dev/stderr"; # 输出无效的分辨率格式到标准错误 / Output invalid resolution format to stderr + next; + } + print fmt, w, h; # 输出格式 fmt, w, h / Output fmt, w, h + } + ' "$input_file") + fi + + # 如果没有解析到任何数据,或者文件不可读取,则返回默认值 / If no data is parsed or file is unreadable, return default values + if [ -z "$parsed_data" ]; then + echo "Warn: No valid config, using default instead." 1>&2 # 输出到标准错误 / Output to stderr + parsed_data=$( + echo "mjpg 640 360" # 默认值 / Default value + echo "yuyv 640 360" # 默认值 / Default value + ) + fi + + echo "$parsed_data" # 返回解析的数据 / Return the parsed data + +} + + + + +########################################################################## +# UVC + +CONFIGFS_PATH="/sys/kernel/config/usb_gadget/g0" +ORIGINAL_DIR=$(pwd) # 记录脚本启动时的目录 / Record the original working directory + +create_frame() { + # Example usage: + # create_frame + + WIDTH=$1 + HEIGHT=$2 + FORMAT=$3 + + if [ "$FORMAT" == "yuyv" ]; then + wdir=streaming/uncompressed/u/${HEIGHT}p + elif [ "$FORMAT" == "mjpg" ]; then + wdir=streaming/mjpeg/m/${HEIGHT}p + else + echo "only support format yuyv/mjpeg!" + exit 1 + fi + + mkdir -p $wdir + echo $WIDTH > $wdir/wWidth + echo $HEIGHT > $wdir/wHeight + echo $(( $WIDTH * $HEIGHT * 2 )) > $wdir/dwMaxVideoFrameBufferSize + echo $(( $WIDTH * $HEIGHT * 2 * 8 * 5 )) > $wdir/dwMinBitRate + echo $(( $WIDTH * $HEIGHT * 2 * 8 * 60 )) > $wdir/dwMaxBitRate + + cat > $wdir/dwFrameInterval < $wdir/dwDefaultFrameInterval + +<< EOF + configure FrameRate + dwFrameInterfal is in 100-ns units (fps = 1/(dwFrameInterval * 10000000)) + 166666 -> 60 fps + 333333 -> 30 fps + 400000 -> 25 fps + 500000 -> 20 fps + 666666 -> 15 fps + 1000000 -> 10 fps + 2000000 -> 5 fps + 5000000 -> 2 fps + 10000000 -> 1 fps +EOF +} + + +# 挂载 UVC ConfigFS / Mount the UVC ConfigFS +mount_uvc_configfs() { + echo "Mounting UVC ConfigFS in $(pwd)" + + # 创建 functions/uvc.usb0 目录 / Create the directory for uvc.usb0 + mkdir -p functions/uvc.usb0 + cd functions/uvc.usb0 + + # 在 functions/uvc.usb0 目录中创建控制头和符号链接 / Create control header and symlink it in uvc.usb0 + mkdir -p control/header/h + ln -s control/header/h/ control/class/fs/ + ln -s control/header/h/ control/class/ss/ + + # streaming_maxpacket sets wMaxPacketSize. Valid values are 1024/2048/3072 + echo 1024 > streaming_maxpacket + # streaming_interval sets bInterval. Values range from 1..255 + echo 1 > streaming_interval + # streaming_maxburst sets bMaxBurst. Valid values are 1..15 + echo 1 > streaming_maxburst + + # 在 functions/uvc.usb0 目录中创建流媒体路径 / Create streaming paths in uvc.usb0 + mkdir -p streaming/uncompressed/u # YUV 目录 / YUV directory + mkdir -p streaming/mjpeg/m # MJPEG 目录 / MJPEG directory + # 执行解析并直接传递给 while 循环进行处理 / Execute parsing and directly pass to while loop for processing + parse_uvc_config "$1" | while read fmt w h; do + echo "Adding: Format: $fmt, Width: $w, Height: $h" # 输出格式、宽和高 / Output fmt, width, and height + create_frame $w $h $fmt + done + mkdir -p streaming/header/h + # 将 YUV 和 MJPEG 目录链接到流媒体头中 / Link YUV and MJPEG to streaming header + ln -s streaming/uncompressed/u/ streaming/header/h/ + ln -s streaming/mjpeg/m/ streaming/header/h/ + # 将 header 链接到 class 中 / Link header to classes + ln -s streaming/header/h/ streaming/class/fs + ln -s streaming/header/h/ streaming/class/hs + ln -s streaming/header/h/ streaming/class/ss + + cd ../.. + ln -s functions/uvc.usb0 configs/c.1 + + echo "UVC ConfigFS mounted successfully in $(pwd)" +} + +# 卸载 UVC ConfigFS / Unmount the UVC ConfigFS +unmount_uvc_configfs() { + echo "Unmounting UVC ConfigFS in $(pwd)" + + unlink configs/c.1/uvc.usb0 + + cd functions/uvc.usb0 + + # 删除流媒体目录 / Remove streaming directories + unlink streaming/class/fs/h + unlink streaming/class/hs/h + unlink streaming/class/ss/h + + unlink streaming/header/h/u + unlink streaming/header/h/m + rmdir streaming/header/h + + rmdir streaming/uncompressed/u/*p + rmdir streaming/mjpeg/m/*p + rmdir streaming/uncompressed/u + rmdir streaming/mjpeg/m + + unlink control/class/fs/h + unlink control/class/ss/h + rmdir control/header/h + + cd ../.. + # 删除 functions/uvc.usb0 目录 / Remove the uvc.usb0 directory + rmdir functions/uvc.usb0 + + echo UVC ConfigFS unmounted successfully in $(pwd) +} + +# 进入工作目录 / Enter the working directory +cd "$CONFIGFS_PATH" || return 1 + +# 处理传入的参数 +# Process the input arguments +case "$1" in + "mount") + mount_uvc_configfs "$2" + ;; + "unmount") + unmount_uvc_configfs + ;; + "server") + ( + echo "Waiting for UDC start..." + while [ -z "$(cat /sys/kernel/config/usb_gadget/g0/UDC)" ]; do + echo -n "." + sleep 1 + done + sleep 2 # necessary delay time + echo -e "\nServer is starting..." # 输出选择了 server 模式 / Output that the server mode is selected + echo -e "===============================\n\n\n" + # 在这里添加你希望在 server 模式下执行的其他操作 / Add other operations you want to perform in server mode here + /etc/init.d/uvc-gadget-server.elf -u /dev/$(basename /sys/class/udc/*/device/gadget/video4linux/video*) -d -i /bin/cat_224.jpg + ) >/tmp/uvc-gadget.log 2>&1 & + ;; + *) + echo "Usage: $0 {mount |unmount|server}" # 提示正确的使用方式 / Prompt the correct usage + ;; +esac + +# 返回原始目录 / Return to the original directory +cd "$ORIGINAL_DIR" || return 1 \ No newline at end of file From c3b98df9aa758f6cef004d53f8a1d0b80f4df963 Mon Sep 17 00:00:00 2001 From: taorye Date: Thu, 12 Dec 2024 18:16:53 +0800 Subject: [PATCH 2/3] fix: increase rootfs.sd's size from 1100M to 1536M --- .../sg200x/sg2002_licheervnano_sd/partition/partition_sd.xml | 2 +- buildroot/configs/cvitek_SG200X_musl_riscv64_defconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/boards/sg200x/sg2002_licheervnano_sd/partition/partition_sd.xml b/build/boards/sg200x/sg2002_licheervnano_sd/partition/partition_sd.xml index 3f772ba9e..fd769f2e4 100644 --- a/build/boards/sg200x/sg2002_licheervnano_sd/partition/partition_sd.xml +++ b/build/boards/sg200x/sg2002_licheervnano_sd/partition/partition_sd.xml @@ -1,4 +1,4 @@ - + diff --git a/buildroot/configs/cvitek_SG200X_musl_riscv64_defconfig b/buildroot/configs/cvitek_SG200X_musl_riscv64_defconfig index d54eeae0d..e8be2933d 100644 --- a/buildroot/configs/cvitek_SG200X_musl_riscv64_defconfig +++ b/buildroot/configs/cvitek_SG200X_musl_riscv64_defconfig @@ -601,7 +601,7 @@ BR2_PACKAGE_AXP2101=y BR2_TARGET_ROOTFS_EXT2=y BR2_TARGET_ROOTFS_EXT2_4=y -BR2_TARGET_ROOTFS_EXT2_SIZE="1100M" +BR2_TARGET_ROOTFS_EXT2_SIZE="1536M" BR2_ROOTFS_OVERLAY="$(TOPDIR)/board/cvitek/SG200X/overlay" BR2_PACKAGE_BUSYBOX_CONFIG_FRAGMENT_FILES="$(TOPDIR)/board/cvitek/SG200X/busybox-extra.config" From 71bcc307549685f191c534c114d728a091fad108 Mon Sep 17 00:00:00 2001 From: taorye Date: Fri, 13 Dec 2024 11:56:19 +0800 Subject: [PATCH 3/3] fix: high CPU usage for select unneeded dfds while !udev->is_streaming --- .../overlay/etc/init.d/uvc-gadget-server.elf | Bin 22504 -> 22504 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/buildroot/board/cvitek/SG200X/overlay/etc/init.d/uvc-gadget-server.elf b/buildroot/board/cvitek/SG200X/overlay/etc/init.d/uvc-gadget-server.elf index 993e01f22a48c68f8ee2bef52be6e1ed3ccfe97f..5316261ebd3dfea488b112b34d3fa68c0853f968 100755 GIT binary patch delta 2793 zcmZ`*4R9036~5KqHPrYA4V8aFYoFK_sZB8PPYedd1c*pPoB}p+FbM=s5XP7`C=e1krOA0(g|mem_wDJ< zs$r^`)9!xz-uJzI`*!a}52Mk;s7ZQYtA|p5TaS($&p^My&9j%IU*o~qjc6r)Hgh8q zaBpS}dKEvI#pnE49^3S;j~$#mbRe?DD$tF%H*0;)4tcEb2to5wXfw{v=FwkpQ?`tD z;kuml1+DT}wE4sVu(?~`;AQJ?`&O8~QyKQ)Z*zWp;Pz* z^91?;XFptv&V*ilxYmHqHna25$GDhXi$1|Gvh$FHx3h)l5`K$)4@j!*zeMN??pq|I zt2kKVw%zD!Y4dCoeJ;Oj=9pkCQ(fn^=EV^d4P9D%8KIka|I**1FL9A$JsQO?I~JpV z;tq$+_Agm#zdEwT7Zz`w46I!(JgMg58+^fG%adj4)D?ZsYH^xVv-H35_YNDc!0aV` zcBAG=CuC_;L`SWbBLv_0b4C& z7R}*@;P6q};c;DH4mg}m<4z5y=Ysv2G`>!^w}JhKh`PD?r!SbF-&SWuNMat#aWG|G z2UEJ!L0N(#<2)uY{KB{t*@8tnpLr}k&Xk%GOfftq@YvyTm=g6Ivm{Q?BvWKc?&26n zJSh+?IneE6D<<}cv57qanp(?MRS(-6!t@`kEi9#SE>G&1UMFz-`z^ESS=GV!ROCSdlwE1++Nk2=uaI3{^EF&hh-#F$A>O}LTdXcsMAE> zCNu(9^%>A;VYeS87^W%1O!7?;fm<|9?mi6UkT^J+cQx*LuvdTGJI!5qNDGor4v>sf$MssbBIz*-U?C;LB9Akx%iwy1tfGbRql98UN`;j`cRGld%GbZq9i~$R; z7<=dp=qSD(F5`V#F?iWMEjG%_UKVYaF1OfDds$d1k-N`sJy=Axh+%r=k>O-;mVEAVX52S}3@2B0<`)@>>cEY(FWxtk220nXJ@#Xnu(-UA#t!YHkx_FDI;? zy*m6Iaaquhh`@Em**$J_na0y@;!?05CSF;isvOKR$5SgJt2`WqLcRgFWO9JqyUFDw zcS)-#QcUTsBy$ArO15Hh(#4eU0=A^gO!0kft;L+=K&qL7p*x5FObss9j455 zC#5B@1-t;UfXF{Q-XY?Y)8Xa7@eTwKDGzwb3eRiD5DuWW3Au_vmUavWMZX8;p>6XJ z*_zXk+`#_Sw~zzI{jh~s-huBYa&&jYeF@)QPRQusKDAEBVtI8Xkp@n=XRV>(7$r2o zxrg9LO0$lnV&3gjJx2bY#}@*vZV3sf@a#J$$_1a(yUbXMmibD(4tN(kx7Cpk$2tQ= zRU-;7E9;!o>O$(bUaop(i%< G82$?|1py=g delta 2876 zcmZ`*e^gV~9eB)E#;YW%f^m2>*o8chtz*!RBV5pZXm zbGi3^?&tgY-tYH*?|qrI zj2hH}pIE|cu{2$M&c+VL-ahHurxWNmaQBkk+Jn+`UN1qH#nHn!Gm}S0@cv8*9mRFp z-8sjkX@Bd5lfap2Xtc5oQ?@eoeObYYztnzR+bK=+O*XbZc2OXxc+$Ob>1h=@?f(4n zClPe%dM!d{aBdchdhzzG708WW$|^(W@X@Rr$b)~o>@0c@ugR`O7qBzC6b<0(*=^_& zemRFlgZLo)AHV}S<-iZ;Ordk`drveW^hftEa>o%GazB?pgU~1LZx#p$eT1(t&!EdV zv#=J8xc^XCn}U3;>t(4Gh>{?Z! z|Dvz0-TazpE3cPQImQ*pkmJ1Dy4r^(-J`3oA~c0N*S>@e!} z_a$$~_3?c+k9hB*edl&zo1BXW_=-`#EG&8ZKULOrn&Q;>Dm{b$W7P8$td1(HRS8R4 zC3&lT3aZoerX&>AlGi_y#0M0d2L6>KeoK|$rvd-+JUroB%mDr{!FjS_on~5-F!&l6 ze4I4cqBzI_gO8GUaRR4vf&XC=-=*;Lf&T%b?(BW`C#gSvtxkuKk6EWRGR0OSv#DiG z-Ex=6nBMU+yfNtY?ZYC?Fq?u=#-xrih0qG1sUwU*9XY@;PX!|a z#}o!5KBtY{`tYzAczD=OQ#(1!&&Ldn9{P8>HkOh#H^$FXW=E^Kp)UwVUvb(zsAaPN z8@%Weacgl7?`yZfe7fQ@fvchFeyyy}_Q59egV94yTe&*HnVle}s<#!^>=_6Ek_XpQ(S8aF^^GHQ+Wv0XG(T_G{?iF( z3uOC;1wL@D9G%wg)*}aA_GZYuwDOv!0nh*=|2i8P&7N{R633A$v74>a|8k}u*i9dkz4-?ZIk)~pmcbA8}m{x~vW%V&qrg=Bz{YOD8+%g0Y zan#CM{zg**x9t?cROR)tgHz;zwzAd$)P!M~1OD$)!5V(GG%H&jW(q>-ux~JI3dkm1 zbUNvAZ)q+M3W=$$i%Wlx4y9Px-J*Wfw@>uY6<2FRORu)+FIicl#~2i$mVl?S>P0NJ z?OEyYRPN%iIOdcY#!#B<0*Zq<9#F0|trlV1(&} zF}oG^Y$bb+H4G6}DtA!sRb4|FeReo_`vac+bS&-)j*^_ybbmcz{Js)2GRcTJPs@Ef z_s{or8Y&B?=BwooN{Qr^$e9|*sjK@Jbq=sXaiVj^Sd0(F(Iz>~2YvqLPi?@636N@JY5YfNM ztaFBWsGo4sOk58JW5jHPq@7e3L=umPL|Nm9+Pnkh9{wwNP9r6dyZVPZQKXnn_rgps zO~Ii>V&!CwjI8WGz9Ks9=0i4JTRDX_>N|}ee!f=)Se6;FI=(ifLhMF+Dp#r>qQ;w> zX&pFdd@-~a9F3AO)=-bFxAzI;GQ55n(1}OUqG9+-n1TlxaE*W8@W(2YB^~4Sb!4vM!3|F43gZU z9wk+>$;AILX}nuUPbO@<6+=xI+rW z_r3_XmY-Q_Fd_LT>dtTN;>h4PCinBEOKCg){WPLpEk+dS?TP*h^tTdYf|K?I%%3em z)KO>(rUCppXsysD-9I#cJI!tS&VEhG3#;)bFBsDlmj)9~*|UC8*c{(M*!|3&u9W`* DfA