TinyUSB HIL 设备卡死恢复指南:Linux 内核侧 usbfs 设备锁与 D 状态进程的排查与处置

发布时间:2026/9/29 3:24:12

TinyUSB HIL 设备卡死恢复指南:Linux 内核侧 usbfs 设备锁与 D 状态进程的排查与处置 嵌入式驱动开发通信物联网【免费下载链接】tinyusbAn open source cross-platform USB stack for embedded system项目地址https://gitcode.com/gh_mirrors/ti/tinyusb点击查看免费下载导读本文以 TinyUSB 仓库中.claude/skills/usb-kernel-recover/SKILL.md为骨架系统讲解 HILHardware-in-the-Loop测试机架上 Linux 宿主机侧 USB 设备卡死wedge的完整恢复流程从 D 状态进程的定位、设备锁机制的原理到分级的恢复动作rung 1~4、控制器故障处置与机架健康验收。读者学完后能在 ci.lan、hifiphile/tusb 或开发机bench PC上对无法枚举、进程挂死在 D 状态的设备或 fixture 做出安全、可验证的恢复并规避常见的误操作。1. 问题本质usbfs ioctl 与设备锁的不可中断性TinyUSB HIL 机架上的卡死wedged通常表现为设备不再枚举或触及 USB 的进程testusb、JLinkExe、uhubctl、openocd、libusb 工具陷入 D 状态不可中断睡眠无法退出。核心机制在 Linux 内核一个卡住的 usbfs ioctl 持有该设备的device_lock。usbdev_do_ioctl调用的是不可中断版本的usb_lock_device内核 v6.12.96 的devio.c:2609。其下的驱动在无超时的wait_for_completion()上等待usbtest.c:1404usb_sg_waitmessage.c:765。任何同样需要该锁的路径都无法介入——只有两条杠杆可行在设备端让 URB 失败rung 1与端口侧数据线断电rung 2。2. Triage先找到锁的持有者ps -eo pid,stat,etimes,wchan:22,args | awk $2 ~ /D/ sudo cat /proc/pid/stack # 不会打开节点因此不会阻塞判断规则S 受害者victim。加锁的 sysfs读操作使用usb_lock_device_interruptiblesysfs.c:124-139共 11 处可被信号杀死timeout能限定它们。可忽略它们会自行解除。D 持有者或走了不可中断路径的写入者。栈内容含义处置usbdev_ioctl 驱动模块[usbtest]所有者持有锁rung 3 — 终局usbdev_ioctl无驱动帧所有者等待一个 URBrung 1DUT/ rung 2probeusbdev_open、sysfs 读受害者忽略tee .../usbtest/new_id、bind、unbind会扩散锁的受害者停止发出这些命令kworker 中的hub_event卡在所有者身后的拆卸rung 3驱动绑定写入并非被动__device_driver_lockdrivers/base/dd.c以不可中断方式获取device_lock()并获取device_lock(parent)——因为usb_bus_type设置了.need_parent_lock truedriver.c:2048每次都会持有 HUB 的锁这就是一个卡死的端口拖垮整条总线的机制。用无锁属性lock-free attrs把持有者映射到 busportdevnum、idVendor、idProduct是usb_descriptor_attr*纯sysfs_emitsysfs.c:688-705for d in /sys/bus/usb/devices/bus-*/; do [ $(cat $d/devnum) devnum ] echo $d $(cat $d/idVendor):$(cat $d/idProduct) done grep -l SERIAL /sys/bus/usb/devices/*/serial # 仅在健康设备上可用3. Shield使用 libusb 类工具的前置条件卡死的设备会阻塞每个读取其加锁属性的枚举器——JLinkExe、uhubctl、openocd 的 HID 回退都在此列。chmod 000让 VFS 在-show()运行前就拒绝读取于是这些枚举器跳过它继续枚举。chmod永不阻塞inode setattr无show()因此在完全卡死的设备上依然有效。sudo .claude/skills/usb-kernel-recover/scripts/usb_recover.sh shield busport $$ # 叶子 父 hub 根 hub先记录原始模式 sudo .claude/skills/usb-kernel-recover/scripts/usb_recover.sh shield-status # 谁持有什么、所有者存活/已死、哪些已重新枚举 sudo .claude/skills/usb-kernel-recover/scripts/usb_recover.sh unshield busport $$ # 恢复已记录的模式所有者为 pid 或已死时空要点所有者 pid 是恢复会话你的 shell、编排进程不是短命的sudo陈旧 shield 的所有者已消失shield-status会说明。绝不盲目 unshield存活的异主 shield 会被拒绝。根 hub 是共享的因此第二个触碰它的 shield 会被拒绝先完成或 unshield 第一个。以非 root 身份运行恢复工具root 拥有CAP_DAC_OVERRIDE会无视000照样阻塞。叶子 shield 会在重新枚举时消失新 kobject、新 inodeunshield只恢复存活的原始对象其余报 gone。它绝不从兄弟设备复制模式九个属性中两个是 644其余是 444。JLinkExe 总是需要 shield即使带-USB/-SelectEmuBySN也一样为了找到其 probe它会读取宿主机上每个 USB 设备的product、serial与bNumInterfacesstraceci.lan 2026-09-21而这些属性都在各自设备的锁下提供。对固定了vid_pid或走interface/jlink.cfg的 openocd 则不需要hil_flash.convoy_safe——它们在libusb_open之前就跳过异设备不读取其他设备的加锁属性。4. 恢复阶梯The Rungs直接跳到 triage 指定的那一级Rung 1 — 卡死的 DUT通过其自身的 probe 复位从 HIL 名册解析该板卡的恢复烧录器recovery flasher取flasher_recover否则取主flasherhil_flash.recover_flasherprobe-sn无论哪种都是主烧录器的uid。convoy_safehil_flash.convoy_safe的烧录器无需 shieldopenocd 形式openocd -c adapter serial probe-sn flasher args -c init; reset run; shutdown其他工具只能在 shield第 3 节后运行然后 unshieldJLink 形式sudo .claude/skills/usb-kernel-recover/scripts/usb_recover.sh shield busport $$ printf r\ng\nq\n /tmp/rec.jlink JLinkExe -device DEV -if SWD -speed 4000 -SelectEmuBySN probe-sn \ -autoconnect 1 -nogui 1 -CommandFile /tmp/rec.jlink sudo .claude/skills/usb-kernel-recover/scripts/usb_recover.sh unshield busport $$在 park-flash 之前复位非破坏性被测固件保留供事后分析、无 flash 磨损、不会留下坏 park 镜像——wfe/wfipark 曾在 mimxrt1064_evk 与 max32666fthr 上通过一次断电把 SWD 变砖。ResetTarget实测 128-129 ms单次分别清除了 57 → 0、26 → 0、5 → 0 个 D 状态进程。机制芯片复位拉低上拉 →usb_hcd_flush_endpoint以-ESHUTDOWN解除 URBhcd.c:1783→ completion 触发 → ioctl 返回 → 锁释放。在 i.MX RT 上有效USBCMD.RS 0 脱离RT1050 RM Rev 3 p.2453在 DWC2 上也有效——2026-08-16 在 stm32f407disco 上实测r; g得到usb 13-2.2: USB disconnect, device number 107325 ms 后重新枚举。单纯的halt不行核心仍在运行并保持上拉。Park-flash--recover-board/--recover-fw即usbtest.py自动化的动作是复位够不到外设时的回退。投递必须 convoy-safe固定vid_pid或走interface/jlink.cfg的 openocd或 esptool-p ttyACM。JLinkExe 需要 shield第 3 节。Rung 2 — 卡死的 PROBEroot-cycleprobe 没有 probe 可复位它端口侧断电是唯一避开 KERNEL 设备锁的杠杆。它命令 ROOT hub绝不触碰卡死设备的device_lock——这正是 rung 1 和 3 危险而这一级不危险的原因。这与机架的板卡 flock是不同锁而本 rung 仍需要那些 flock它会弹跳根端口下的每个 fixture包括另一任务正在烧录途中的板卡。先取锁用后释放python3 test/hil/helper/hil_lock.py hold --all --config this hosts config --reason root-cycle busport sudo .claude/skills/usb-kernel-recover/scripts/usb_recover.sh root-cycle busport [expected-serial] python3 test/hil/helper/hil_lock.py release --all # 无需 --config它会遍历锁目录--all对单根端口来说很粗但没有任何机制能把 sysfs busport 映射到板卡名因此它是唯一真正覆盖爆炸半径的预留方式hold接受任意字符串所以手写仅兄弟板的 hold 看似成功实则没有预留任何东西。被以hil_test.py名义拒绝说明 CI 正在测试中——等待不要强推。给脚本卡死 probe 自己的 busport如13-1.6而不是13-1这个 hub 路径脚本自己推导根端口而 expected-serial 守卫与成功检查都读取你传入的路径。这会弹跳该根端口下的每个fixture本机最多 25 个。Renesas 卡宣称支持ppps但并不实现VBUS 保持供电只有 D/D− 跌落因此这是强制重新枚举绝不是断电——固件卡死的设备可以安然度过。成功判据是 sysfs inode 变化而不是 uhubctl 的退出码。Rung 3 — 终局持有锁的驱动 ioctl无软件解药任务不可中断SIGKILL 只排队不送达。用sysrq重启绝不用reboot(2)——优雅重启会运行device_shutdown()获取每个设备锁并在卡死的那个上卡住。echo b | sudo tee /proc/sysrq-trigger # 之后sync; sudo umount -aRung 4 — 虚拟机管理程序仅 ci.lan且在记录的八次卡死中从未需要qm stop vmid qm start vmid在 PVE 宿主机上。VM重启不可靠——hub 可能跨 PCIe 复位锁存。5. 控制器死了怎么办pci-rebind特征xhci-pci-renesas addr: Timeout while waiting for setup device command、该控制器上的设备枚举失败或总线消失——与单个设备卡死相对。以上 rung 无效控制器本身需要重新初始化。sudo .claude/skills/usb-kernel-recover/scripts/usb_recover.sh pci-rebind pciaddr # unbind bind 整个 xHCI sudo .claude/skills/usb-kernel-recover/scripts/usb_recover.sh pci-bind pciaddr # 仅在它最终无驱动时使用成功 rebind 后每个 fixture 都会重新枚举并且它重编该控制器拥有的每条总线号ci.lan 上 2026-08-17 总线 17、18 回来变成 1、2因此 rebind 前要按 rung 2 的方式取机架级 hold、之后释放并重新推导 busport。设备锁 convoy 存活期间不要使用它——参见常见错误。6. 如果没有 D 状态进程设备是死了或沉默了不是卡死。sudo .claude/skills/usb-kernel-recover/scripts/usb_recover.sh authorized busport会反配置并重新配置它usb_set_configuration(dev, -1)然后重新选择hub.c——修复陈旧的驱动/接口状态不会重新插拔usb_device存活因此多数 probe 保留 sysfs 节点。若仍无效设备是卡死而非沉默——转 rung 1 或 2。resolve dev-node把/dev/ttyACM3映射为 busport。它不可中断地取usb_lock_devicehub.cusb_deauthorize_device因此只在无任何 D 状态进程时安全。7. 宣布机架健康前的验收ps -eo stat,args | awk $1 ~ /D/ | wc -l # 必须为 0 timeout 15 lsusb # rc 0 且设备数合理 sudo uhubctl -l bus -p port # 0000 off 再也没回来 sudo uhubctl -l bus -p port -a on实测教训D 状态列表完全干净时仍有 5 块板缺失因为usb17-port2停在disable1。8. 常见错误清单uhubctl -a cycle对根端口不使用-S。它写 sysfsdisable而disable_store不可中断地取usb_lock_device(hdev)并在其内部调用usb_disconnect(child)port.c——面对卡死的子设备它会阻塞并持有根 hub 的锁毒化整条总线。usb_recover.sh传-S。echo 1 .../remove想让卡死设备消失remove_store是 sysfs.c 中唯一取不可中断usb_lock_device的属性sysfs.c:765。它会加入 convoy 而不是清除它。对任何卡死设备执行authorized——同样的不可中断锁。驱动 unbind/bind/sys/bus/usb/drivers/usb/{unbind,bind}通过usb_generic_driver_disconnectgeneric.c做同样的反配置/重配置但还取父 hub 的锁need_parent_lock严格更糟它因此被从usb_recover.sh中移除。对卡死的设备用pci-rebind。它是死控制器的解药见第 5 节不是设备锁 convoy 的解药在活跃的 D 状态 URB 下重新 bind 可能挂死并把控制器留在无驱动状态、所有 fixture 离线实测一次。用pci-bind addr恢复。写/sys/bus/pci/devices/addr/reset——本机架无控制器支持 FLR因此它在活跃驱动之后变成总线复位卡停止、宿主机断电。复位受害者的板卡。曾有两块板在找到持有者之前被无辜复位。按devnum映射不要按哪块板应该运行。假定只有一个控制器。实测三个 xHCI 控制器上 26 个 D 状态进程全部由一台设备上的一次 probe 复位清除。9. 机架布局与脚本实现要点ci.lanreadlink -f /sys/bus/usb/devices/usbN得到其 PCI 地址sudo uhubctl列出它能驱动的根 hub 及其 PCI 地址。八块 Renesas uPD720201 控制器——0000:01:00.0至0000:08:00.0在两块卡上——在其 USB2 与 USB3 根 hub 上都宣称每端口ppps但不实现硅片从不拉低 VBUS在05–08卡上实测01–04未测假设相同因此 cycle 只是重新枚举端口仅此而已。不要在本机架上把 uhubctl 的ppps读作电源控制。哪棵树挂着哪些 probe 随重新布线而变化因此要现场推导lsusb -s bus:而非信任静态映射。2026-09-22 验证此处hathach的sudo免密因此上面每一级 rung 都无需提示直接运行。从脚本usb_recover.sh的源码可进一步确认几个关键实现细节路径脚本被 shield 的加锁属性列表固定为bNumInterfaces bmAttributes bMaxPower configuration bConfigurationValue product manufacturer serial avoid_reset_quirk而descriptors、busnum、devnum、speed、idVendor、idProduct是无锁属性libusb 需要它们永不列入第 31 行注释。lock_read()对锁下属性的每次读取用timeout 2限定有界返回?表示无应答——这是 root-cycle 成功判定的前提防止在真卡死时无限期阻塞。重新枚举的成功判据sysfs_gen()用stat -c %i busport/目录 inode 的尾随斜杠/sys/bus/usb/devices/busport是带独立 inode 的符号链接无斜杠时 stat 的是链接而非设备本身值永不变化第 95-97 行注释kernfs 的 inode 单调分配真实断开会重建 kobject 使 inode 改变。shield先快照全部对象与其 inode、模式再执行 chmod失败时按记录回滚绝不从兄弟设备复制模式unshield只恢复仍携带记录 inode 的存活对象其余报 gone。参数用正则白名单校验USBPATH_RE、PCI_RE、DRIVER_RE以阻断路径穿越require_usb_controller拒绝非 USB 控制器非0x0c03xx类的 PCI 函数防止误伤共享 HIL 宿主上的存储/NIC。root-cycle通过-S强制走 libusb 路径直接向根 hub 发断电控制传输前置无子设备断开并在循环内以最多 10 秒等待sysfs_gen变化作为唯一成功判定——uhubctl 即使无操作也返回 0其退出码不证明任何事。与 HIL 测试体系的联动该恢复流程在 TinyUSB HIL 测试体系中的位置板卡锁由 hil_lock.py 用/tmp/tinyusb-hil-locks/下的内核 flock 按板卡仲裁CI runner 的hil_test.py自我加锁reasonhil_test.py被该 reason 拒绝说明 CI 正在测试等待数分钟重试而非强推。机架级操作root-cycle、pci-rebind、控制器复位——都会重编总线号必须先hold --all --config host config再release --all。flasher_recover与convoy_safehil_flash.py名册中可选的flasher_recover键指定恢复投递方式convoy_safe判定烧录器能否绕过毒化节点送达恢复——三种形态合格固定vid_pid的 openocd在libusb_open前就continue跳过异节点、esptool-p ttyACM命名端口从不枚举 usbfs、走interface/jlink.cfg的 openocdlibjaylink 只开 SEGGER 设备。名册实例可见 tinyusb.json如 frdm_k64f 的主烧录器为 jlink、flasher_recover为 openocd over jlink.cfg。后池恢复阶段hil_recover.pyhil_test.py对带.wedged标记的板卡在 worker 池关闭后逐卡恢复——按需 shield仅当恢复烧录器不 convoy-safe、probe 复位、持有者幸存则重刷、unshield、验证完整持有者扫描为空 DUT 重新枚举、以该证据hil_lock.py wedged clear清除标记。恢复在 fork 出的 supervisor 会话中运行预算由HIL_RECOVERY_TIMEOUT600 s限定shield 需要非 root 免密 sudoroot 无视 shield 的 000 模式。usbtest.py的 wedge 判定usbtest.py通过wedged_pids()的 /proc 扫描把 D 状态持有者关联到 DUT 节点配合confirmation_of(stuck, complete)产出wedge_confirmation/cleared/confirmed/unverifiedconfirmed即写入.wedged标记。结语Linux 内核的usb_lock_device不可中断性决定了面对 usbfs 层卡死的设备任何也取同一把锁的软件路径sysfs 写、remove、authorized、优雅重启都会加入 convoy 而非清除它。TinyUSB HIL 机架的恢复策略因此围绕两条真正的杠杆展开——在设备端失败 URBrung 1与端口侧数据线跌落rung 2——以usb_recover.sh的 shield、root-cycle、pci-rebind 等原语落实为可脚本化、有守卫、可验证的操作并用.wedged标记与证据验证把恢复闭环回 HIL 测试流程。掌握这一套流程就能把一次整机架宕机级的 USB 卡死收敛为几分钟内、单点、无破坏的定点处置。赞分享嵌入式驱动开发通信物联网【免费下载链接】tinyusbAn open source cross-platform USB stack for embedded system项目地址https://gitcode.com/gh_mirrors/ti/tinyusb点击查看免费下载相关推荐Matter设备状态恢复出厂重置与配置备份在智能家居系统中Matter设备原Project CHIP的状态管理是确保设备稳定运行的关键环节。当设备出现连接故障、配置错误或需要转移所有权时 出厂重物联网智能家居嵌入式通信MemOS内存管理系统深度探索高效处理LLM长期记忆的5个技巧MemOS内存管理系统深度探索高效处理LLM长期记忆的5个技巧 MemOS作为一款开源的Memory OS框架专为构建内存原生AI智能体而设计核心功能涵盖人工智能大模型Agent 记忆AI AgentRAG知识图谱dsh-plugin如何用3分钟从国家中小学智慧教育平台批量下载电子课本tchMaterial-parser下载工具完全指南如何用3分钟从国家中小学智慧教育平台批量下载电子课本tchMaterial parser下载工具完全指南 还在为寻找教学资源而奔波吗每次备课都需要在多个平台网页爬虫教育上一篇边缘计算三步落地Baetyl 在 AI 一体机与 5G 路侧盒子的实战下一篇在 Fairseq 中复现大规模反向翻译以 WMT18 英德翻译为例Understanding Back-Translation at Scale 实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/29 3:24:12

基于神经网络的配送路径优化算法:从建模到实践落地

简介:这是一份基于神经网络求解配送路径优化问题的学术论文PDF,面向物流工程、算法研究与神经网络应用方向的从业者、研究生及竞赛爱好者,重点解决车辆调度中路径规划易陷入局部最优的难题。文件为单份PDF,大小仅194KB&#xff0c…

2026/9/29 3:19:12

Cesium实时流体模拟:用浅水方程实现洪水淹没与动态水面效果

1. 这个标题到底在解决什么问题刚看到“Cesium 基于浅水方程流体模拟”这个标题的时候,我第一反应是:这是把玩地图的人和解偏微分方程的人拉到了一张桌上。Cesium 本身不是渲染引擎里的通用 GPGPU 平台,它优先服务的是经纬度、地形、影像、三…

2026/9/29 5:49:18

Model-Optimizer:面向生产部署的模型结构级轻量化方法论

1. 这不是“一键加速”工具,而是一套模型瘦身手术方案“Model-Optimizer”这个词最近在工程团队的 Slack 频道里高频出现,但它绝不是某个新发布的 GUI 软件图标,也不是某家云厂商刚推的付费 API 接口。它本质上是一套面向生产环境的模型轻量化…

2026/9/29 5:49:18

从零构建语言模型:AI工程的极简实践与避坑指南

如果只看现在的招聘 JD,你可能会觉得「AI 工程」是被大厂的 GPU 集群、算法团队和 MLOps 平台垄断的领域,个人开发者只能站在别人的模型后面调参数。但我决定反着来。两年前我开始了一个项目 ai-engineering-from-scratch,目标是在没有现成 t…

2026/9/29 5:49:18

用Dify打造AI复盘助手:低代码搭建复盘机器人的实战指南

1. 为什么做 Hindsight:复盘这件事,AI 能帮什么忙先说说这个项目的来由。手头项目新版本上线后出了事故,团队开了场复盘会,大家坐在一起,把经过聊了两小时,结论却依然停在“下次注意”。会后整理纪要&#…

2026/9/29 5:49:18

C++11类的新功能:移动语义、右值引用与构造函数现代化改造

做C开发十年,说句实在话,C11是这门语言的分水岭。它不是单纯加了几个语法糖,而是把整个写代码的思路从“对象在拷贝”拉到了“对象在移动”。尤其是类这一块,以前写构造函数、析构函数、拷贝赋值,三条腿走路&#xff1…

2026/9/29 5:49:18

Model-Optimizer全链路优化:从训练收敛到推理部署的实践指南

在深度学习这个圈子里,“Model-Optimizer”这个词挺有意思的——你说它是训练时那个决定模型能不能收敛的优化器吧,它确实是;但往深了一想,把一个训练好的模型打磨到能上线、能商用,中间还有一大堆优化工作要做&#x…

2026/9/28 3:03:23

东莞市品牌网站建设报价常见报错与解决

东莞品牌网站建设报价单背后:一份保姆级建站教程避坑实录 网站做好了没人访问,这大概是很多老板最头疼的事。花了大几万做的品牌站,上线后流量惨淡,比路边摊还冷清。别急着骂外包公司,很多“东莞品牌网站建设报价”里藏着不少猫腻,比如用模板站冒充定制…

2026/9/28 6:05:15

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/28 6:07:41

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/29 0:04:04

AI Evals实战指南:从零搭建LLM应用评估体系与CI/CD集成

1. 为什么AI Evals值得你花时间搞明白做LLM应用的人,迟早会撞上同一堵墙:模型输出飘忽不定,今天答得好好的,明天换个问法就胡说八道。你改了一版提示词,感觉好像好了点,但到底好了多少?说不清。…

2026/9/29 0:04:04

Java采购管理系统实战:从数据库设计到事务一致性

简介:这是一套面向Java Web初学者与课程设计者的采购管理系统完整源码,采用JSP技术搭建,配合MySQL数据库,用于解决企业采购信息的管理问题,适合作为毕业设计、课程大作业或进销存类项目的参考模板。系统实现了用户登录…

2026/9/29 3:53:39

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/26 19:58:38

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/28 1:59:25

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑