RK1808 GT911触摸屏驱动调试全流程:从设备树配置到坐标校准

发布时间:2026/10/21 13:45:45
RK1808 GT911触摸屏驱动调试全流程:从设备树配置到坐标校准 1. 项目缘起与整体设计思路RK1808这颗芯片在边缘计算和AI推理盒子里出镜率很高双核Cortex-A35加上独立的NPU功耗和算力平衡得不错。但真正落到产品化阶段触摸屏这块的调试往往比跑通NPU demo更折磨人。我最近刚完成一个基于RK1808的工业手持终端项目屏幕用的是7寸1024x600的IPS面板触摸方案选了GT911电容触摸芯片走I2C接口。整个调试过程踩了不少坑从设备树配置到中断触发方式再到坐标映射的边角问题前后折腾了将近一周才彻底稳定。这篇文章就是把这套调试流程完整拆开讲清楚。不管你是刚接触Rockchip平台的新手还是从全志、瑞芯微其他芯片转过来的老手只要涉及到RK1808的TP驱动调试这里面的思路和操作步骤都能直接参考。我会从硬件接口确认开始一路讲到驱动加载、设备树配置、中断调试、坐标校准最后附上常见问题的排查方法。内容偏向实操尽量把每个参数为什么这么设讲明白而不是只丢一堆配置让你抄。先说一下整体方案选型。RK1808的触摸屏接入方式主要有两种一种是走I2C接口的外挂触摸芯片比如GT911、FT5x06、GT928这些另一种是走SPI或者USB的触摸方案。工业手持设备上I2C方案用得最多因为引脚少、驱动成熟、成本低。GT911在这类场景里算是明星型号了支持多点触控最多5点分辨率适配范围广I2C地址可以配置成0x5D或者0x14中断引脚和复位引脚分开控制驱动层面Linux内核已经有现成的gt9xx驱动可以移植。选GT911的另一个原因是它的固件配置比较灵活可以通过I2C写入配置参数来调整灵敏度、报点率、坐标范围等。但这也意味着如果配置不对会出现触摸漂移、断触、坐标翻转等各种奇怪现象。所以调试的核心其实就两件事一是让驱动正确加载并识别到芯片二是让上报的坐标和屏幕实际坐标对得上。整个调试流程我习惯分成四个阶段硬件确认、驱动移植、设备树配置、功能验证与调优。硬件确认阶段要量I2C波形、确认中断引脚和复位引脚的电平逻辑驱动移植阶段要把gt9xx驱动编进内核或者做成模块设备树配置阶段要写对I2C节点、中断触发方式、复位时序功能验证阶段要用evtest、getevent这些工具看报点数据再根据实际情况调坐标映射和灵敏度。注意RK1808的I2C控制器有多个要确认你用的那一路I2C在设备树里没有被其他外设占用尤其是I2C地址冲突的问题GT911的0x5D和某些EEPROM的地址会撞车。2. 硬件接口确认与上电时序检查2.1 I2C总线与引脚分配确认在动软件之前硬件这块必须先用示波器或者逻辑分析仪确认一遍。RK1808的I2C接口电平是1.8V还是3.3V这个要跟触摸芯片的供电电平匹配。GT911的VDD供电范围是2.8V到3.3V但I2C电平可以单独设如果RK1808的I2C是1.8V电平而GT911的上拉电阻接到了3.3V那就会出现电平不匹配表现为I2C通信时好时坏或者根本读不到设备。我一般会先量这几个点VDD电压是否稳定在3.3V、I2C的SCL和SDA上拉电阻是否接对、INT引脚和RST引脚的默认电平状态。GT911的上电时序有要求RST引脚要先拉低至少10ms然后拉高INT引脚在上电阶段要保持低电平芯片才会进入正常的工作模式。如果INT引脚在上电时被拉高芯片可能会进入烧录模式或者地址变成0x14。具体到RK1808这边I2C控制器的引脚在设备树里是通过pinctrl来配置的。你需要确认用的是哪一路I2C比如i2c1、i2c2还是i2c4然后找到对应的引脚编号。RK1808的引脚复用比较灵活同一个物理引脚可以配成GPIO、I2C、SPI或者UART所以pinctrl配置必须和硬件原理图对上。i2c1 { status okay; clock-frequency 400000; gt911: touchscreen5d { compatible goodix,gt911; reg 0x5d; interrupt-parent gpio0; interrupts RK_PB0 IRQ_TYPE_EDGE_FALLING; reset-gpios gpio0 RK_PB1 GPIO_ACTIVE_LOW; irq-gpios gpio0 RK_PB0 GPIO_ACTIVE_HIGH; touchscreen-size-x 1024; touchscreen-size-y 600; touchscreen-inverted-x; touchscreen-swapped-x-y; }; };上面这段设备树配置是核心。clock-frequency设成400kHz是GT911支持的最高速率实际调试时如果I2C走线比较长或者干扰大可以先降到100kHz确认通信正常再往上提。interrupts里的触发方式我选的是下降沿触发因为GT911的中断引脚在报点时会产生一个低脉冲下降沿触发比较稳。但有些硬件设计是上升沿有效这个要根据实际波形来定。reset-gpios和irq-gpios的GPIO编号要跟原理图完全对应RK1808的GPIO分组是gpio0到gpio4每组32个引脚。比如RK_PB0就是gpio0组的第8号引脚。这里最容易出错的就是把GPIO编号算错导致复位引脚控制不了芯片一直处于复位状态。2.2 上电时序与复位电路检查GT911的上电时序如果不对芯片根本不会响应I2C。标准时序是这样的VDD上电后RST引脚保持低电平至少10ms然后拉高同时INT引脚在RST拉高后的100ms内要保持低电平。如果INT引脚在这段时间内被拉高芯片会切换到0x14地址这时候如果你的驱动只扫0x5D就会找不到设备。我遇到过一种情况硬件工程师把INT引脚直接上拉到了3.3V结果GT911上电后地址变成了0x14驱动一直probe失败。后来把INT引脚改成GPIO控制在上电阶段先拉低等RST拉高后再释放问题就解决了。所以设备树里irq-gpios这个属性不只是用来申请中断的还要在驱动初始化阶段控制它的电平状态。另外RST引脚的复位脉宽也要注意。GT911要求复位低电平持续时间在10ms到100ms之间太短了芯片复位不彻底太长了也没必要。我在驱动里一般会加一个20ms的延时确保复位可靠。static int gt911_reset(struct i2c_client *client) { struct gt911_ts_data *ts i2c_get_clientdata(client); gpio_direction_output(ts-reset_gpio, 0); msleep(20); gpio_direction_output(ts-reset_gpio, 1); msleep(100); return 0; }这段复位代码里先把RST拉低20ms然后拉高再等100ms让芯片内部固件启动完成。这个100ms的等待时间不能省否则紧接着发I2C命令芯片可能还没准备好。实操心得如果手头没有示波器可以用万用表量RST和INT的电压变化虽然看不到波形但至少能确认电平逻辑对不对。上电后RST应该是高电平INT在没触摸时也应该是高电平触摸时会有低脉冲。3. 驱动移植与内核配置3.1 GT911驱动源码获取与适配Rockchip的SDK里一般已经带了gt9xx的驱动路径通常在kernel/drivers/input/touchscreen/gt9xx/下面。如果没有可以从Linux内核社区找goodix的驱动或者从芯片原厂提供的驱动包移植。GT911和GT928的驱动框架基本一样主要区别在配置参数和固件版本。拿到驱动源码后第一件事是确认它支持的I2C设备ID列表里有没有GT911的ID。GT911的I2C地址是0x5D和0x14芯片ID寄存器读出来应该是0x39 0x31 0x31也就是ASCII的911。如果驱动里只写了GT928的ID那probe的时候会匹配失败。static const struct i2c_device_id gt9xx_ts_id[] { { gt911, 0 }, { gt928, 0 }, { gt9147, 0 }, { } }; MODULE_DEVICE_TABLE(i2c, gt9xx_ts_id); static const struct of_device_id gt9xx_dt_match[] { { .compatible goodix,gt911 }, { .compatible goodix,gt928 }, { } }; MODULE_DEVICE_TABLE(of, gt9xx_dt_match);设备树里的compatible属性必须和驱动里的of_device_id匹配上否则驱动不会probe。我见过有人设备树写的是goodix,gt9xx但驱动里只有goodix,gt911结果一直匹配不上查了半天才发现是字符串不一致。3.2 内核配置与编译选项驱动要编进内核需要在make menuconfig里打开对应的选项。路径是Device Drivers - Input device support - Touchscreens - Goodix I2C touchscreen。如果驱动是作为模块编译的还要确保CONFIG_INPUT_EVDEV是打开的否则evtest用不了。# 内核配置检查 grep -r GT9XX .config # 应该看到 CONFIG_TOUCHSCREEN_GT9XXy CONFIG_INPUT_EVDEVy编译的时候要注意RK1808的内核版本一般是4.4或者4.19不同版本的内核API有差异。比如4.4的内核里GPIO操作还是用gpio_direction_output这种老接口4.19以后推荐用gpiod_系列接口。如果驱动是从别的平台移植过来的这部分要改。另外RK1808的DTS文件一般在kernel/arch/arm/boot/dts/rk1808-xxx.dts你要找到自己板子对应的dts文件把触摸屏节点加到正确的I2C控制器下面。编译完内核后用make dtbs单独编译设备树然后替换到boot分区。注意RK1808的boot分区里内核和设备树是打包在一起的替换的时候要用resource_tool或者mkbootimg重新打包不能只替换dtb文件。3.3 驱动加载与probe过程分析驱动编好后系统启动时会在内核日志里打印probe信息。用dmesg | grep gt9xx可以看到驱动加载过程。正常的日志应该是这样的[ 2.345678] gt9xx 1-005d: gt9xx_probe start [ 2.345789] gt9xx 1-005d: reset gpio: 8, irq gpio: 9 [ 2.346012] gt9xx 1-005d: GTP read version: 0x39 0x31 0x31 [ 2.346123] gt9xx 1-005d: GTP config version: 0x5A [ 2.346234] gt9xx 1-005d: gt9xx_probe success如果probe失败日志里会有错误码。常见的有-ENODEV表示I2C通信失败-EIO表示读芯片ID失败-EPROBE_DEFER表示GPIO或者regulator还没准备好。根据错误码可以快速定位问题方向。我遇到过一次-EPROBE_DEFER原因是复位GPIO在pinctrl里被其他驱动占用了导致gpio_request失败。后来在设备树里把那个GPIO从其他节点里删掉问题就解决了。所以设备树里的GPIO资源分配要全局检查不能有冲突。4. 中断调试与坐标映射调优4.1 中断触发方式与报点率调试GT911的中断引脚在检测到触摸时会输出低电平脉冲脉冲的宽度和报点率有关。默认配置下报点率是100Hz也就是每10ms报一个点。如果中断触发方式设错了会出现丢点或者重复报点的问题。用cat /proc/interrupts | grep gt9xx可以看到中断计数。如果触摸时计数不增加说明中断没触发要检查GPIO方向、触发边沿、以及中断是否被正确申请。如果计数增加很快但evtest看不到报点可能是I2C读数据失败要检查I2C通信是否正常。# 查看中断统计 cat /proc/interrupts | grep gt9xx # 输出示例 45: 1234 gpio0 9 Edge gt9xx_ts # 用evtest查看报点数据 evtest /dev/input/event2 # 触摸屏幕时应该看到ABS_MT_POSITION_X/Y事件报点率如果太低触摸会感觉卡顿太高了又浪费CPU。GT911的配置寄存器里可以设报点率一般设成100Hz到120Hz之间比较合适。工业手持设备上我一般设100Hz兼顾流畅度和功耗。4.2 坐标映射与屏幕方向适配坐标映射是TP调试里最容易出问题的环节。屏幕的物理方向和触摸芯片的坐标系不一定一致可能出现X轴翻转、Y轴翻转、XY交换等情况。设备树里的touchscreen-inverted-x、touchscreen-inverted-y、touchscreen-swapped-x-y这三个属性就是用来调坐标映射的。具体怎么设要看屏幕的安装方向和触摸芯片的贴装方向。我的经验是先用evtest看原始坐标然后跟屏幕的实际坐标对比。比如触摸屏幕左上角evtest报的坐标是(0, 600)那就说明Y轴反了需要加touchscreen-inverted-y。如果触摸左上角报的是(0, 0)但触摸右上角报的是(600, 0)那就说明XY交换了需要加touchscreen-swapped-x-y。/* 坐标映射配置示例 */ touchscreen-size-x 1024; touchscreen-size-y 600; touchscreen-inverted-x; /* X轴翻转 */ touchscreen-inverted-y; /* Y轴翻转 */ touchscreen-swapped-x-y; /* XY交换 */这四个属性的组合有8种可能实际调试时可以用一个简单的测试方法在屏幕四个角依次触摸记录evtest的坐标然后对照屏幕实际坐标就能确定需要哪些属性。我一般会画一个表格来对照触摸位置屏幕坐标evtest原始坐标需要的属性左上角(0,0)(0,600)inverted-y右上角(1024,0)(1024,600)inverted-y左下角(0,600)(0,0)无右下角(1024,600)(1024,0)无实操心得坐标映射调好后最好用ts_calibrate或者自己写个简单的画板程序验证一下在屏幕上画线看是否跟手。如果线条有锯齿或者偏移可能是坐标范围设得不对touchscreen-size-x和touchscreen-size-y要跟屏幕的实际分辨率完全一致。4.3 多点触控与手势支持GT911支持最多5点触控驱动里要正确上报ABS_MT_SLOT、ABS_MT_TRACKING_ID、ABS_MT_POSITION_X/Y这些事件。如果多点触控有问题比如只能识别一个点或者点与点之间串扰要检查驱动里的slot管理逻辑。/* 多点触控上报示例 */ for (i 0; i ts-num_points; i) { input_mt_slot(ts-input_dev, i); input_mt_report_slot_state(ts-input_dev, MT_TOOL_FINGER, true); input_report_abs(ts-input_dev, ABS_MT_POSITION_X, ts-coords[i].x); input_report_abs(ts-input_dev, ABS_MT_POSITION_Y, ts-coords[i].y); } input_mt_sync_frame(ts-input_dev); input_sync(ts-input_dev);这段代码里input_mt_slot用来切换当前上报的slotinput_mt_report_slot_state用来标记该slot是否有手指按下。如果漏掉了input_mt_sync_frame多点触控可能会异常。我在调试时遇到过两点触摸时坐标跳变的问题后来发现是slot没有正确释放加上input_mt_sync_frame后就正常了。5. 常见问题排查与实战避坑指南5.1 驱动probe失败问题速查驱动probe失败是最常见的问题表现是/dev/input/eventX设备节点不存在或者dmesg里有错误日志。下面这个表格整理了我遇到过的几种典型情况和解决方法错误现象可能原因排查方法解决方法probe返回-ENODEVI2C通信失败用i2cdetect扫总线检查I2C引脚、上拉电阻、供电probe返回-EIO读芯片ID失败量I2C波形检查复位时序、INT电平probe返回-EPROBE_DEFERGPIO被占用查gpio_request日志检查设备树GPIO冲突设备节点存在但无报点中断未触发查/proc/interrupts检查中断触发方式、GPIO方向报点坐标乱跳坐标映射错误用evtest看原始数据调整inverted/swapped属性I2C通信失败的时候先用i2cdetect -y 1扫一下总线看0x5D地址上有没有设备响应。如果没有响应再量I2C的SCL和SDA波形确认有没有时钟和数据输出。如果波形正常但设备不响应可能是供电或者复位问题。5.2 触摸漂移与断触问题处理触摸漂移一般有两个原因一是坐标映射没调好二是触摸芯片的配置参数不合适。GT911的配置参数里有一项是touchscreen-size-x和touchscreen-size-y这两个值要跟屏幕分辨率一致。如果设大了或者设小了坐标就会偏移。断触问题通常是中断触发方式或者报点率设置的问题。如果中断是边沿触发但触摸芯片的中断信号是电平保持的就会丢中断。这时候要改成电平触发或者在驱动里加一个workqueue来轮询。我一般优先用边沿触发因为效率高但如果硬件设计是电平保持的就只能用电平触发。还有一种断触是I2C通信超时导致的。GT911在报点时I2C通信比较频繁如果I2C速率太高或者走线太长可能会出现通信失败。这时候可以把clock-frequency从400kHz降到100kHz试试。我在一个项目里遇到过连续触摸时偶尔断触后来把I2C速率降到200kHz就稳定了。5.3 低功耗与唤醒问题工业手持设备对功耗有要求触摸屏在休眠时也要进入低功耗模式。GT911支持手势唤醒可以在休眠时检测双击、滑动等手势。但手势唤醒的配置比较麻烦需要在驱动里把手势参数写到芯片的配置寄存器里。休眠流程一般是这样的系统进入suspend时驱动调用gt9xx_suspend把GT911设成低功耗模式同时使能手势唤醒。唤醒时GT911产生中断驱动在中断处理里读取手势信息然后上报一个按键事件来唤醒系统。static int gt9xx_suspend(struct device *dev) { struct gt911_ts_data *ts dev_get_drvdata(dev); disable_irq(ts-irq); gt911_enter_sleep(ts); enable_irq_wake(ts-irq); return 0; }这里要注意enable_irq_wake的调用它让中断引脚在系统休眠时还能唤醒CPU。如果忘了调这个休眠后触摸就没反应了。另外GT911进入休眠前要先把中断禁掉否则休眠过程中产生的中断可能会干扰休眠流程。注意手势唤醒功能会增加休眠功耗如果产品对功耗要求特别严格可以关掉手势唤醒只保留基本的触摸唤醒。6. 调试工具与效率提升技巧6.1 常用调试命令与工具调试TP驱动手头有几个工具会事半功倍。evtest是最常用的可以实时看报点数据getevent跟evtest类似但输出格式更简洁i2cdetect和i2cget用来扫总线和读寄存器dmesg看内核日志cat /proc/interrupts看中断统计。# 扫描I2C总线 i2cdetect -y 1 # 读取GT911的芯片ID寄存器 i2cget -y 1 0x5d 0x8140 w # 实时查看触摸事件 getevent -l /dev/input/event2 # 查看中断统计 watch -n 1 cat /proc/interrupts | grep gt9xxi2cget读寄存器的时候要注意GT911的寄存器地址是16位的读的时候要用w参数表示16位地址。比如读芯片ID的寄存器地址是0x8140命令就是i2cget -y 1 0x5d 0x8140 w返回的应该是0x39 0x31 0x31。6.2 日志分析与问题定位方法内核日志是排查问题的第一手资料。我一般会在驱动里加一些dev_dbg或者pr_info打印把关键流程的返回值都打出来。比如I2C读写的返回值、GPIO操作的结果、中断触发的次数等。这样出问题的时候看日志就能快速定位到哪一步失败了。ret gt911_i2c_read(ts-client, addr, buf, len); if (ret 0) { dev_err(ts-client-dev, i2c read failed: %d\n, ret); return ret; }日志里如果看到i2c read failed: -6-6是-ENXIO表示I2C设备没有响应这时候就要去查硬件了。如果是-110那是-ETIMEDOUT表示I2C超时可能是速率太高或者总线被拉住了。6.3 性能优化与稳定性提升TP驱动调通之后还要做一些优化让触摸体验更好。首先是报点率100Hz是基本要求如果CPU负载允许可以提到120Hz。其次是滤波算法GT911的原始坐标会有轻微抖动驱动里可以加一个简单的滑动平均滤波让坐标更平滑。/* 简单的滑动平均滤波 */ static void gt911_filter_coords(struct gt911_ts_data *ts) { static int filter_buf[5][2]; int i, sum_x 0, sum_y 0; for (i 4; i 0; i--) { filter_buf[i][0] filter_buf[i-1][0]; filter_buf[i][1] filter_buf[i-1][1]; } filter_buf[0][0] ts-x; filter_buf[0][1] ts-y; for (i 0; i 5; i) { sum_x filter_buf[i][0]; sum_y filter_buf[i][1]; } ts-x sum_x / 5; ts-y sum_y / 5; }这个滤波算法很简单就是取最近5个点的平均值。实际测试下来坐标抖动会明显减小但会引入一点点延迟。如果对延迟敏感可以把窗口缩小到3个点。稳定性方面还要考虑I2C通信的错误恢复。如果I2C读写失败驱动里要有重试机制连续失败多次后再报错。GT911在受到干扰时偶尔会出现I2C通信异常重试一般能恢复。for (retry 0; retry 3; retry) { ret gt911_i2c_read(ts-client, addr, buf, len); if (ret 0) break; msleep(10); } if (retry 3) { dev_err(ts-client-dev, i2c read failed after 3 retries\n); return ret; }这个重试机制在实际项目里救过我好几次尤其是工业环境里电磁干扰比较大的时候没有重试的话触摸会偶尔失灵。7. 从调试到量产的关键检查项7.1 批量生产的一致性验证实验室里调通不代表量产没问题。不同批次的触摸芯片固件版本可能不一样屏幕的贴合精度也有差异。量产前一定要做小批量验证至少测20台以上确认每台的触摸坐标都在允许误差范围内。我一般会写一个简单的测试脚本自动在屏幕的9个区域依次触摸记录坐标偏差。如果偏差超过5个像素就要考虑是不是屏幕贴合或者触摸芯片贴装的问题。#!/bin/bash # 触摸坐标自动测试脚本 for i in $(seq 1 9); do echo 请触摸第 $i 个区域... timeout 5 getevent -l /dev/input/event2 | head -5 done这个脚本只是示意实际量产测试会用专门的工装和上位机软件来自动化完成。7.2 温度与湿度环境测试工业手持设备的工作温度范围一般是-20度到60度触摸屏在这个温度范围内都要能正常工作。低温下触摸芯片的灵敏度会下降高温下可能会出现漂移。所以量产前要做高低温测试确认触摸功能正常。湿度方面主要是防止凝露导致触摸误触发。如果产品要在高湿环境下使用触摸芯片的配置里可以适当降低灵敏度或者加一层防水膜。7.3 长期稳定性与老化测试老化测试一般跑72小时以上连续触摸和休眠唤醒循环。我遇到过一次老化测试中触摸失灵的问题后来发现是I2C总线上挂的设备太多长时间工作后某个设备把总线拉死了。解决方法是在驱动里加一个I2C总线恢复机制检测到总线异常时主动复位I2C控制器。/* I2C总线恢复 */ static void gt911_i2c_recover(struct i2c_client *client) { struct i2c_adapter *adap client-adapter; i2c_recover_bus(adap); msleep(10); gt911_reset(client); }这个恢复机制在长时间运行的项目里很有必要尤其是总线上挂了多个I2C设备的时候。8. 个人实操体会与后续扩展方向整个RK1808 TP驱动调试走下来最深的体会就是硬件和软件必须结合起来看。很多问题表面上是驱动配置不对实际上是硬件设计有缺陷。比如中断引脚的默认电平、I2C上拉电阻的阻值、复位电路的RC参数这些硬件细节都会直接影响驱动能不能正常工作。另外设备树的配置一定要跟原理图逐行对照GPIO编号、I2C地址、中断触发方式一个都不能错。我习惯在调试前先把原理图里的触摸屏部分打印出来用笔把每个引脚的功能标上然后对着写设备树这样能避免很多低级错误。后续如果还要扩展可以考虑把GT911的固件升级功能加上。GT911支持通过I2C更新固件这样量产时如果发现触摸参数需要调整不用换芯片直接升级固件就行。固件升级的流程稍微复杂一点需要进入烧录模式然后分块写入配置和固件数据但掌握了之后会很方便。最后再分享一个小技巧调试的时候如果怀疑是触摸芯片的问题可以找一个同型号的已知良好的模块替换上去如果换了就好了那就是芯片或者贴装的问题如果换了还是一样那就是驱动或者设备树的问题。这个替换法能快速缩小问题范围比一点点查日志快得多。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询