ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

VersaLogic Android评估套件解析:从AOSP到工业嵌入式实战

VersaLogic Android评估套件解析:从AOSP到工业嵌入式实战 昨天在展会上路过VersaLogic的展台看到他们推出了一款新的Android Demo/Eval Kit旁边立了块“Enter to win”的抽奖牌。作为常年和嵌入式Linux打交道的老玩家我一开始觉得这就是个营销噱头但仔细了解之后发现这个评估套件背后代表的东西还挺值得聊一聊。Android在工业嵌入式领域的渗透速度比很多人想象中要快得多而VersaLogic这种老牌工业单板机厂商愿意专门做一套Android评估方案本身就是一个明确的行业信号。这篇文章我就从这块评估套件出发聊聊它究竟是什么、解决了什么问题、拿到手之后怎么跑起来、以及Android嵌入式开发中那些不翻车就学不到的实操经验。无论你是做工业HMI、医疗设备、边缘计算网关还是想把手头的x86工控板改成Android系统这篇都值得看完。1. 这块评估套件到底是什么为什么会有人需要它1.1 从“能跑Linux”到“要跑Android”嵌入式行业的风向变了过去我们在工业项目里选型默认就是Linux Qt或者Linux 自研Web界面稳是稳但有个痛点怎么也绕不过去应用生态太贫瘠。客户要一个好看点的交互界面、要一个能快速迭代的App、要支持蓝牙耳机/打印机/扫码枪这些外设Linux这边要么自己从头写驱动和协议栈要么把开源组件缝缝补补一个项目下来光UI和适配就占掉大半工期。Android的出现改变了这个局面。它底层就是Linux内核驱动模型、内存管理、文件系统这些老底子都在但上面多了一层成熟的应用框架和极其丰富的生态。比如你用AndroidStudio开发一个工业控制界面Material Design组件直接拖拽蓝牙、Wi-Fi、USB、串口都有现成的API摄像头扫码、语音播报、远程OTA全部有标准方案。这套组合拳对工业客户来说吸引力极大——他们终于可以像做消费类App一样去做工业产品了。VersaLogic这次推出的Android Demo/Eval Kit核心价值就是把这个迁移过程的门槛拆掉。他们本身就是做工业级单板计算机的老厂常年给军工、医疗、交通运输行业供货硬件可靠性和生命周期支持是立身之本。现在他们在自家的x86平台上把Android系统适配好、驱动调通、示例程序写好打包成一个开箱即用的评估套件实际上是在告诉市场你们不用再自己从AOSP源码开始折腾了我们已经把最脏最累的底层活干完了。1.2 评估套件里通常都有什么硬件、BSP、示例代码、文档虽然每个厂商的评估套件内容会有差异但作为行业通用做法这类套件一般会包含四层东西。第一层是硬件本体通常是一块工业级单板计算机带CPU、内存、eMMC存储引出串口、USB、以太网、GPIO、CAN等工业接口有的还配好了触摸屏模组和外壳。第二层是BSPBoard Support Package这里是关键中的关键包括适配好硬件的外设驱动、设备树、U-Boot引导程序、内核Image、以及构建好的Android系统镜像。第三层是示例应用源码一般会有一个或多个Demo App演示怎么用Java/Kotlin调用GPIO、串口、I/O外设怎么和上层业务集成。第四层是完整的文档和快速入门指南包含硬件原理图、引脚定义、烧录步骤、开发环境搭建教程。我见过不少客户评估嵌入式板卡时只关注硬件参数表拿到板子之后才发现软件支持一塌糊涂连个能用的系统镜像都没有或者驱动缺这缺那光让板子正常启动就折腾了两周。Demo/Eval Kit的意义就在于它把“能跑”这个最基本也最容易被忽略的验收项直接兑现了。你拿到手之后第一件事不是去找技术支持而是通电、开机、跑Demo先确认硬件和系统的基本盘稳不稳再决定要不要深入评估。1.3 “Enter to win”背后的市场逻辑回到标题里的“Enter to win”这其实是厂商非常典型的市场活动手法填个邮箱、留个联系方式就有机会免费获得一套评估套件。表面上看是抽奖实际上是两个目的——第一用低门槛方式获取精准的潜在客户线索敢去填表的都是对这类硬件有真实需求的工程师第二让评估套件尽可能多地流向目标用户手里形成口碑扩散。我做项目选型这些年对这类活动一向是积极响应的反正填表不要钱万一中了还省了几千块的评估经费。更重要的是即便没中也能通过这个渠道和厂商的FAE建立联系后续申请样片或者拿技术文档都方便很多。2. 整体设计与方案选型思路为什么是这个组合优势在哪2.1 为什么是Android而不是纯AOSP或其它系统这里有个经常被误解的点Android和AOSPAndroid Open Source Project安卓开源项目不是一回事。AOSP是开源的底层系统Google的Android在它之上还叠加了GMSGoogle Mobile Services谷歌移动服务、各种认证和闭源组件。工业产品一般不会用带GMS的完整Android因为你既不需要Google Play商店、也不需要Google全家桶而且它们还涉及授权费用和数据合规问题。VersaLogic这种评估套件基本都会明确标注用的是AOSP裁剪版也就是去掉了Google私有组件的纯净Android系统。那为什么不用Debian或者Yocto Linux答案很简单应用层开发效率和生态丰富度完全不在一个量级。Linux下你要做一个带图形界面的数据采集终端可能需要自己选型GUI框架、自己处理触摸驱动、自己写软键盘逻辑Android下这些东西全是现成的Activity、Service、ContentProvider、View体系一套成熟得不能再成熟的模型摆在面前招一个Android应用工程师比招一个嵌入式Linux图形开发工程师容易得多。2.2 x86平台跑Android兼容性取舍与性能考量VersaLogic的看家本领是x86架构的工业单板机所以他们的Android套件跑在x86上并不让人意外。确实ARM是Android的“原生”平台x86属于后来者但经过这么多年的优化x86上跑Android的体验已经很成熟了。很多x86平板、Box PC、工业一体机都在用Android系统Google官方也长期维护x86的AOSP分支。x86跑Android有两个好处是ARM平台不好比的。第一是性能释放更充分x86处理器的多核性能和内存带宽普遍更高跑重型工业应用、做视觉检测、同时开多个业务App的时候底气更足。第二是外设兼容性广工业场景里大量使用PCIe扩展卡、USB转串口、网口、并口这类接口x86平台的成熟生态让这些外设的Linux驱动天然可用Android底层的Linux内核可以直接继承。当然x86也有个绕不开的劣势——功耗和发热比同性能的ARM高不少也没有ARM平台那种深度待机的能力。如果你的产品是电池供电、对功耗极其敏感的场景那x86就不太合适还是老老实实选ARM平台。2.3 BSP定制程度决定了后期要填多少坑我评估一块安卓工业板卡最先看的就是BSP的成熟度。BSP做得好不好直接决定了你后期应用开发会不会被底层问题反复打断。一次合格的BSP适配工作至少要覆盖这几个方面Bootloader要稳定可靠支持网络启动、U盘升级、看门狗喂狗等工业特性内核要打上适合该硬件的patch把串口、CAN、GPIO、RTC、看门狗等外设驱动调通Android系统层要做裁剪去掉不需要的系统应用和服务配置好SELinux策略避免审批流程繁琐的安全策略挡住外设访问。VersaLogic这类老牌工业厂商做BSP的优势在于他们的硬件平台本身是长期量产的底层的BIOS/UEFI、芯片组驱动、工业接口方案都已经过大规模验证而不是搞一块公版开发板塞给你。Android系统跑在这种经过验证的硬件平台上稳定性自然有保障。这也是为什么同样的AOSP源码有人编译出来跑一周就死机有人跑一年都没事差距往往就在BSP这层。3. 核心细节解析与实操要点从零开始跑通这块安卓评估板3.1 开发环境搭建Android Studio、SDK、NDK、交叉编译链拿到评估套件之后第一件事是搭建开发环境。如果你以前只做过嵌入式Linux开发这里的环境搭建思路和Linux有相似之处但流程要繁琐不少。对于x86平台的评估板你不需要配置交叉编译链来编译整个系统镜像——厂商一般会直接提供编译好的image你要做的是搭建应用开发环境。应用开发环境的核心是Android Studio这是Google官方的IDE下载安装之后还要装Android SDK Platform-Tools包含adb、fastboot、对应APILevel的SDK Platform、以及一个JDK。这里有个X86平台特别需要注意的细节如果你的评估板是x86架构而你的开发机是ARM架构的Mac或者某些ARM架构的开发板那就需要安装对应的x86_64系统镜像并在创建模拟器时选择正确的ABI。ABI不匹配是新手最常见的报错来源装了个arm64的APK往x86设备上跑直接提示“INSTALL_FAILED_NO_MATCHING_ABIS”。我用过不少版本的Android Studio总的来说用最新稳定版就行不用追Preview版。SDK Manager里把需要的Platform Tools、Build Tools、NDK、CMake都装齐然后按照厂商文档设置环境变量。这里踩过一个坑Android Studio在下载SDK时偶尔会卡在网络源上如果遇到这种问题建议在SDK Manager里手动配置镜像源或者用离线包方式导入千万别把下载挂了就跑去做别的回来发现进度条还是0%。3.2 烧录与调试fastboot、ADB、串口、GDB、OpenOCD系统镜像烧录这块Android和嵌入式Linux有本质区别。Linux一般用U-Boot网络加载或者SD卡整卡刷写Android更常见的是fastboot模式和ADB配合。fastboot是Android底层的一个刷机协议运行在Bootloader阶段。步骤大概是用USB线连接评估板和开发机进入fastboot模式不同厂商按键方式不同有的需要短接跳线有的在启动时按住某个按键然后在开发机上执行fastboot devices确认设备识别接着依次烧录各个分区。典型的x86 Android分区包括boot、system、vendor、data、cache这几个执行命令类似fastboot flash boot boot.img fastboot flash system system.img fastboot flash vendor vendor.img fastboot flash userdata userdata.img fastboot reboot这里要强调一个实际经验烧录之前先备份原始的userdata分区尤其是厂商预置了某些校准参数或测试程序的时候。我遇到过几次手滑把设备信息分区格式化了导致硬件序列号丢失的情况折腾了很久才从工程师那里要到恢复工具。如果不确定某个分区是干什么的先查文档别乱动。日常调试最常用的还是ADB。设置好开发板上的“开发者选项”和“USB调试”之后插上USB线adb devices就能看到设备。后续的安装应用、看日志、远程执行shell命令全部通过ADB完成adb install app.apk adb shell adb logcat -v time app.log如果程序崩溃了adb logcat里的AndroidRuntime异常信息就是第一手的排查依据。注意logcat的缓冲区是循环覆盖的复现问题前先adb logcat -c清空日志复现后马上抓取避免关键日志被冲掉。对于底层驱动的调试光靠ADB不够还要用串口和JTAG。串口是看内核日志的保底手段很多系统起不来的场景只能用串口看U-Boot和内核打印OpenOCD配合JTAG可以做到硬件级别的断点调试排查驱动和启动代码里的疑难杂症但配置复杂我一般只有在内核早期启动卡住、不知道卡在哪个驱动上的时候才会用这一招。3.3 第一个Android Demo从Hello World到控制真实硬件环境通了之后跑第一个Demo要循序渐进别一上来就整花活。我的习惯是分三步走。第一步验证工具链。用Android Studio新建一个空工程编译安装到评估板上屏幕上能看到一个Hello World页面说明SDK、ADB、驱动、签名全部正常。第二步跑厂商给的预置Demo App。VersaLogic这类评估套件的Demo通常会覆盖几个典型外设比如一个App里包含GPIO点灯、串口收发、读取板载温度传感器、通过CAN总线收发报文等模块。运行这个App的过程本质上就是验证BSP对硬件外设的支持情况。如果点灯模块正常点亮串口能收发数据温度能正确读出来那说明BSP这些驱动都调通了。如果某个功能点了没反应也别急着怪硬件先看logcat有没有权限报错或者设备节点找不到的异常。第三步自己写一个App去调用真实硬件。Android应用层一般不能直接访问/dev/gpiochip0、/dev/ttyS0这类设备节点需要借助JNI或者厂商提供的SDK封装。一种常见做法是用Java写上层界面通过JNI调用C/C库C层再通过Linux系统调用来操作硬件设备节点。这个链路复杂归复杂但也是工业Android开发的基本功值得花时间吃透。3.4 系统裁剪与性能调优让评估板适合量产评估套件的默认系统镜像一般是偏向通用演示的带了一些用不上的App和服务。真要往量产走第一件事就是裁剪系统去掉不必要的系统应用比如浏览器、图库、音乐播放器、禁用用不到的硬件服务比如NFC、蓝牙如果产品不需要、精简开机动画、把预装的应用压到最少。这部分操作需要重新修改AOSP源码并编译系统镜像工作量不小但收益明显——系统启动时间能缩短、内存占用能降下来。性能调优这块工业场景主要看两点稳定性和流畅度。稳定性通过长时间压测来验证让设备连续跑7x24小时同时记录关键进程的内存占用、CPU使用率、温度变化观察有没有内存泄漏或者热降频的现象。流畅度则关注界面渲染如果发现界面卡顿可以用开发者选项里的“显示GPU渲染”功能看看有没有掉帧然后针对性地优化减少布局层级、避免主线程做耗时操作、把大图片移到后台加载。4. Android嵌入式开发中最容易踩的坑常见问题与排查实录4.1 FileProvider和文件访问改造Android 7以上版本的变化从Android 7.0开始App之间不能直接通过file://的方式共享文件了必须用content://配合FileProvider来分享。这个改造让很多从嵌入式Linux转过来的开发者头疼不已——原来写个文件路径传过去就能访问现在还要配置provider、定义XML路径规则。实际开发中的典型报错是FileUriExposedException应用一运行就崩。解决办法分两步第一步在AndroidManifest.xml里注册FileProvider并在meta-data中指定res/xml/file_paths.xml第二步在file_paths.xml里配置你要共享的路径例如paths external-path nameexternal_files path./ /paths这样配置之后分享文件时通过FileProvider提供的content://com.example.app.fileprovider/external_files/xxx来访问就正常了。这个坑看起来简单但涉及的文件路径类型很多内部存储、外部存储、缓存目录、根目录配置一旦漏项就会闪退排查起来还不太直观。建议开发前先把所有要用到的路径类型梳理一遍一次性配全。4.2 Binder与跨进程通信不可见但无处不在的性能瓶颈Binder是Android系统里最核心的进程间通信机制所有跨进程调用都走它。理解Binder有多重要你应用里启动一个Activity、调用一个系统服务、操作一次文件底层全都要经过Binder。如果Binder调用频繁或者传递的数据量过大就会造成系统卡顿。工业App里常见的一个坑是在循环监测线程中高频读取传感器数据每次读取都通过Binder调用硬件服务结果系统被Binder驱动拖垮整个界面都变卡。我给的建议是高频数据采集不要在Java层逐次调用而是用C层批量读取或者把采集逻辑放到系统服务里通过共享内存方式把数据一次性传给应用层。Binder的传输效率是有上限的能用1MB共享内存解决的问题绝不用一万条Binder消息去传。4.3 蓝牙BLE适配工业外设连接的一大堆细节工业产品里蓝牙BLE用得很多扫码枪、测温探头、打印机、血压计都是BLE连接的外设。BLE开发表面上看很简单扫描、连接、发现服务、读写特征值Android的官方API封装得不错。但实际开发中会遇到大量问题扫描不到设备、连接后没多久就断开、数据收发不稳定、Android版本不同行为不一致。根据我的经验BLE适配必须做三件事。第一权限要配全Android 12以上的版本除了BLUETOOTH_SCAN和BLUETOOTH_CONNECT两个运行时权限外还要在清单里声明第二扫描要规范不要在主线程里做扫描扫描回调里处理数据要快慢一点就会漏掉广播包第三连接要做好异常处理BLE连接本身就不稳定一定要加超时重连机制不要指望一次性连接成功。另外要特别注意Android的BLE协议栈在不同厂商设备上的表现差异很大哪怕是同一颗SoC不同主板的天线布局和射频调校也会影响连接稳定性。4.4 OTA升级与系统分区工业设备升级的正确姿势工业设备不像手机可以随便刷机设备部署在现场之后升级必须通过OTAOver-The-Air空中升级方式远程完成而且必须保证升级失败时有回退机制。Android的OTA方案一般是A/B分区即系统有两个完整的系统分区slot A和slot B升级时后台将新系统写入非活跃槽写入完成后切换启动槽位下次开机就用新系统。如果新系统启动失败Bootloader自动回退到旧槽位设备不会变砖。对于评估套件你拿到的默认镜像一般不带完整的A/B分区配置要做OTA还需要额外的系统工程。我的建议是如果产品有OTA需求评估阶段就一定要向厂商确认BSP是否支持A/B分区以及厂商能否提供OTA相关的接口和工具。别到了量产阶段才突然发现底层不支持OTA那时候改硬件就晚了。另外OTA升级一定要考虑断电恢复问题。即使有A/B分区升级过程中也有一个很小的窗口期如果恰好在写入分区时断电两个槽位可能都处于不可用状态。严谨的做法是配合看门狗和电池备用供电把升级过程的意外因素降到最低。4.5 常见问题速查表现象可能原因排查思路解决方案ADB连接不上USB驱动未装、USB调试未开启、线缆供电不足换线、重新安装驱动、检查设备状态部分工业设备需在UEFI中开启USB调试模式应用安装失败提示INSTALL_FAILED_NO_MATCHING_ABISAPK的ABI和系统架构不匹配查看APK中lib目录的架构为x86设备编译x86_64的so库系统启动反复重启内核驱动崩溃、分区损坏接串口看内核日志、进入fastboot模式验证重新烧录kernel和system分区界面卡顿严重主线程被耗时操作阻塞、GPU渲染压力大用ADB抓取ANR日志检查Rendering时间把耗时任务放到子线程优化布局层级传感器读数不对BSP驱动配置错误、Sysfs节点权限不对串口查看dmesg检查设备节点是否存在联系厂商确认BSP版本更新驱动OTA升级后系统起不来新系统镜像损坏、分区表不匹配通过fastboot切换到旧槽位启用A/B分区回退机制检查升级包的完整性校验4.6 独家避坑技巧SELinux策略、看门狗与RTC除了上面这些还有三个不那么明显、但能让项目在后期少遭罪的细节要专门提一下。SELinux策略是Android安全模型的核心它默认把系统的各种访问权限收紧得很严格应用想直接访问/dev/ttyS0这类设备节点通常会被SELinux拦截。就算你通过JNI调了C层代码C层打开设备节点的open()系统调用被SELinux拒绝应用层拿到的就是一个权限错误。在开发阶段可以先把SELinux设为permissive模式快速验证但量产之前一定要把permissive改成enforcing并为自己的应用和硬件服务写好SELinux策略文件。这个工作是Android系统定制的必修课不做好应用在开发机上跑得好好的、一到量产固件上就各种权限异常追查起来让人头大。看门狗是工业设备必备的可靠性组件。系统里的看门狗驱动会在硬件层面周期性喂狗如果系统死机导致喂狗中断看门狗就会强制重启设备。开发阶段看门狗经常被关掉方便调试但到了集成测试和量产阶段一定要把看门狗打开并进行断崖式断电测试、长时间运行死机模拟测试确保设备在任何异常情况下都能自恢复。RTC掉电保持也是工业设备容易漏掉的需求。如果设备需要断电后继续走时间硬件上必须有RTC电池/超级电容并且系统要正确挂载RTC驱动开机时自动从RTC同步时间到系统。不少评估板默认不带RTC电池或者驱动没调好开发时发现设备每次断电重启后时间回到了1970年这时候再去找硬件改版就麻烦了。评估阶段就要把这个点确认清楚。5. 评估套件的价值边界与实践路径5.1 适合用它做什么工业HMI、医疗终端、边缘网关、军工加固拿到这样一块Android评估板哪些项目适合深入哪些本质上就不合适我把话说得直白一点。适合的场景有几个共同特征交互界面要求高、需要Android生态支持、应用层开发资源以Java/Kotlin为主、对实时性要求不极端。工业HMI人机交互界面是我认为最匹配的场景——生产设备上本来就要一个好看的触控屏Android的UI能力比传统HMI方案高出一整个量级做出来的效果完全是两个时代的产品。医疗设备终端也很适合很多床边监护仪、体检设备、康复设备都在Android化因为它们需要友好交互、要连扫码枪和标签打印机、要支持远程运维和升级。边缘计算网关是另一个热门方向——这种设备集成了Wi-Fi、蓝牙、以太网、串口、CAN等一堆接口还要跑容器化或虚拟化的算法推理Android 13以上版本对x86容器和GPU加速的支持已经相当成熟。军工加固设备就不展开说了但行业里确实在加速往Android生态靠拢。5.2 不适合用它做什么硬实时控制、低功耗长续航、极简嵌入式有适合就有不适合。第一类是硬实时控制场景比如运动控制、伺服驱动、电压电流采样这类场景要求确定性的毫秒级甚至微秒级响应Android和Linux一样调度策略并不能保证硬实时。要PLC、FPGA或者RTOS才能扛得住。第二类是超低功耗场景电池供电、待机电流要求微安级的设备Android这套系统太重了不适合它这种场景应该选Zephyr或者FreeRTOS。第三类是成本极敏感的极简嵌入式设备如果产品就是一个传感器节点、一个智能开关用一颗MCU几毛钱搞定的事没必要上一块跑Android的板卡。评估套件本身也有它的定位边界。它的目标是让你“快速验证可行性”而不是“直接量产”。硬件规格、接口布局、散热设计、防护等级这些评估板和你最终的产品设计基本都会不一样。我见过有些团队图省事评估板验证没问题就直接把评估板塞进壳子里量产结果EMC过不了、散热不行、接口位置不对返工成本远超预期。正确做法是拿评估板做软件验证硬件设计另外按产品需求定制主板BSP可以沿用厂商的成果。5.3 拿到套件后完整的评估路径如果是靠“Enter to win”抽中的或者申请了样片我建议用一套系统的评估路径把这块板子的价值榨干别浪费时间在无关紧要的地方。第一个阶段通电验机控制在半天以内。检查配件清单确认电源、串口线、USB线齐全按快速入门文档接线、通电、开机确认系统能正常进入桌面连接ADB确认开发机可以正常访问设备跑一遍厂商预置的Demo把所有外设功能点过一遍记录有没有明显异常。第二个阶段环境搭建一天以内。搭建Android Studio开发环境配好SDK、NDK编译并运行一个自写的Hello World应用确认整个开发闭环是通的然后写一个小工具测试调用一个你最关心的硬件外设比如串口或者GPIO。第三个阶段稳定性验证三到七天。把设备接上你的外设负载让它在持续工作状态下跑长测观察内存占用趋势、CPU温度、系统日志做断电重启、异常断电、网络断连等异常测试。这一步是最容易发现大问题的阶段一定要投入足够时间。第四个阶段业务验证。把自己的核心业务逻辑在评估板上跑起来——不用做完只需要让关键链路能通即可——看性能是否达标、体验是否可接受。到这个阶段你就可以对这块板子和这套Android方案是否适合你的产品做出判断了。6. 写在最后一份过来人的实际心得我在文章最后分享几个这些年做Android嵌入式项目攒下来的体会不一定多深刻但都是踩过坑之后才明白的。第一评估一个平台看文档比看硬件更花时间。厂商提供的文档如果含糊其辞驱动适配、烧录步骤、外设使用说明写得不清楚那这个平台的坑大概率很多。反过来如果文档细致到连SELinux策略怎么写、A/B分区怎么配都有专门的章节那这个平台的成熟度基本靠谱。第二和厂商的FAE处好关系比在网上搜一万篇教程都有用。VersaLogic这类工业厂商的FAE手里有大量内部资料和实际部署案例很多问题在他们的知识库里早有标准答案。申请样片、拉技术微信群、约线上会议把联系方式留好遇到问题先问他们往往十分钟就能解决你搜一整天的难题。第三Android嵌入式开发本质上还是系统工程。应用开发只是水面上的冰山水面下是BSP适配、驱动调优、安全策略、OTA升级一整套支撑体系。评估套件用得越深对这个体系的运转方式就会越了解也越能理解为什么VersaLogic这种工业厂商会在这个时间点推出Android方案——他们深耕硬件和可靠性多年现在补上Android这层软件拼图对整个行业的产品迭代节奏都会是一次加速。最后再补充一个实操小技巧不管你是通过抽奖还是正常渠道拿到评估套件收到货的第一时间建议用手机把开箱过程、硬件接口、系统启动状态全部拍下来留档。别笑这个习惯在后续和厂商沟通时特别有用——你说“主板上有个接口不清楚用途”对方回“你看看是不是JUMPER3旁边的那个”这时候你手里有照片沟通效率完全不一样。工程就是由这些细节堆出来的。
返回列表