2025-09-30 11:56:06 +08:00
<!DOCTYPE html> < html xmlns = "http://www.w3.org/1999/xhtml" xml:lang = "zh-cn" lang = "zh-cn" data-whc_version = "26.0" >
< head > < meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" / > < meta name = "viewport" content = "width=device-width, initial-scale=1.0" / > < meta http-equiv = "X-UA-Compatible" content = "IE=edge" / > < meta name = "description" content = "Layer 由前几节可知 USB 将 Device 进一步细分成了 3 个层级: Configuration 配置、 Interface 接口、 Endpoint 端点。 USB Core 为其中两个层次提供了 Device + Driver 的设备驱动模型,这两个层次分别是 USB Device Layer 和 USB Interface Layer 层,一个 USB Device ..." / > < meta name = "DC.rights.owner" content = "(C) 版权 2025" / > < meta name = "copyright" content = "(C) 版权 2025" / > < meta name = "generator" content = "DITA-OT" / > < meta name = "DC.type" content = "concept" / > < meta name = "DC.contributor" content = "yan.wang" / > < meta name = "DC.date.modified" content = "2024-02-04" / > < meta name = "DC.format" content = "HTML5" / > < meta name = "DC.identifier" content = "usb_host_core" / > < meta name = "DC.language" content = "zh-CN" / > < title > USB Core< / title > <!-- Build number 2023110923. --> < meta name = "wh-path2root" content = "../../../" / > < meta name = "wh-toc-id" content = "" / > < meta name = "wh-source-relpath" content = "topics/sdk/usb/usb-host-core.dita" / > < meta name = "wh-out-relpath" content = "topics/sdk/usb/usb-host-core.html" / >
< link rel = "stylesheet" type = "text/css" href = "../../../webhelp/app/commons.css?buildId=2023110923" / >
< link rel = "stylesheet" type = "text/css" href = "../../../webhelp/app/topic.css?buildId=2023110923" / >
< script src = "../../../webhelp/app/options/properties.js?buildId=20250121171154" > < / script >
< script src = "../../../webhelp/app/localization/strings.js?buildId=2023110923" > < / script >
< script src = "../../../webhelp/app/search/index/keywords.js?buildId=20250121171154" > < / script >
< script defer = "defer" src = "../../../webhelp/app/commons.js?buildId=2023110923" > < / script >
< script defer = "defer" src = "../../../webhelp/app/topic.js?buildId=2023110923" > < / script >
< link rel = "stylesheet" type = "text/css" href = "../../../webhelp/template/aic-styles-web.css?buildId=2023110923" / > < link rel = "stylesheet" type = "text/css" href = "../../../webhelp/template/notes.css?buildId=2023110923" / > < link rel = "stylesheet" type = "text/css" href = "../../../webhelp/template/aic-common.css?buildId=2023110923" / > < link rel = "stylesheet" type = "text/css" href = "../../../webhelp/template/aic-images.css?buildId=2023110923" / > < link rel = "stylesheet" type = "text/css" href = "../../../webhelp/template/footnote.css?buildId=2023110923" / > < link rel = "stylesheet" type = "text/css" href = "../../../webhelp/template/aic-web-watermark.css?buildId=2023110923" / > < link rel = "stylesheet" type = "text/css" href = "../../../webhelp/template/topic-body-list.css?buildId=2023110923" / > < / head >
< body id = "usb_host_core" class = "wh_topic_page frmBody" >
< a href = "#wh_topic_body" class = "sr-only sr-only-focusable" >
跳转到主要内容
< / a >
< header class = "navbar navbar-default wh_header" >
< div class = "container-fluid" >
< div class = "wh_header_flex_container navbar-nav navbar-expand-md navbar-dark" >
< div class = "wh_logo_and_publication_title_container" >
< div class = "wh_logo_and_publication_title" >
< a href = "http://www.artinchip.com" class = " wh_logo d-none d-sm-block " > < img src = "../../../company-logo-white.png" alt = "RTOS SDK 使用指南SDK 指南文件" / > < / a >
< div class = " wh_publication_title " > < a href = "../../../index.html" > < span class = "booktitle" > < span class = "ph mainbooktitle" > RTOS SDK 使用指南< / span > < span class = "ph booktitlealt" > SDK 指南文件< / span > < / span > < / a > < / div >
< / div >
< / div >
< div class = "wh_top_menu_and_indexterms_link collapse navbar-collapse" id = "wh_top_menu_and_indexterms_link" >
< / div >
< / div >
< / div >
< / header >
< div class = " wh_search_input navbar-form wh_topic_page_search search " role = "form" >
< form id = "searchForm" method = "get" role = "search" action = "../../../search.html" > < div > < input type = "search" placeholder = "搜索 " class = "wh_search_textfield" id = "textToSearch" name = "searchQuery" aria-label = "搜索查询" required = "required" / > < button type = "submit" class = "wh_search_button" aria-label = "搜索" > < span class = "search_input_text" > 搜索< / span > < / button > < / div > < / form >
< / div >
< div class = "container-fluid" id = "wh_topic_container" >
< div class = "row" >
< nav class = "wh_tools d-print-none navbar-expand-md" aria-label = "Tools" >
< div data-tooltip-position = "bottom" class = " wh_breadcrumb " > < / div >
< div class = "wh_right_tools" >
< button class = "wh_hide_highlight" aria-label = "切换搜索突出显示" title = "切换搜索突出显示" > < / button >
< button class = "webhelp_expand_collapse_sections" data-next-state = "collapsed" aria-label = "折叠截面" title = "折叠截面" > < / button >
< div class = " wh_print_link print d-none d-md-inline-block " > < button onClick = "window.print()" title = "打印此页" aria-label = "打印此页" > < / button > < / div >
< / div >
< / nav >
< / div >
< div class = "wh_content_area" >
< div class = "row" >
< div class = "col-lg-10 col-md-10 col-sm-10 col-xs-12" id = "wh_topic_body" >
< button id = "wh_close_topic_toc_button" class = "close-toc-button d-none" aria-label = "Toggle topic table of content" aria-controls = "wh_topic_toc" aria-expanded = "true" >
< span class = "close-toc-icon-container" >
< span class = "close-toc-icon" > < / span >
< / span >
< / button >
< div class = " wh_topic_content body " > < main role = "main" > < article class = "- topic/topic concept/concept topic concept" role = "article" aria-labelledby = "ariaid-title1" > < span class = "edit-link" style = "font-size:12px; opacity:0.6; text-align:right; vertical-align:middle" > < a target = "_blank" href = "http://172.16.35.88/tasks/jdssno1uvvbf2mltu9kb9v3if05d5gopuakboe8hlud18rma/edit/F:/aicdita/aicdita-cn/topics/sdk/usb/usb-host-core.dita" > Edit online< / a > < / span > < h1 class = "- topic/title title topictitle1" id = "ariaid-title1" > USB Core< / h1 > < div class = "date inPage" > 4 Feb 2024< / div > < div style = "color: gray;" >
Read time: 5 minute(s)
< / div > < div class = "- topic/body concept/conbody body conbody" > < section class = "- topic/section section" id = "usb_host_core__section_fvy_tnz_21c" data-ofbid = "usb_host_core__section_fvy_tnz_21c" > < h2 class = "- topic/title title sectiontitle" > Layer< / h2 >
< div class = "- topic/p p" data-ofbid = "d280064e27__20250121171751" > < br / > < div class = "imagecenter" > < img class = "- topic/image image imagecenter" id = "usb_host_core__image_gvy_tnz_21c" src = "../../../images/usb/usb_host_drv_dev.png" alt = "image1" / > < / div > < br / > < / div >
< p class = "- topic/p p" data-ofbid = "d280064e32__20250121171751" > 由前几节可知 USB 将 < code class = "+ topic/ph pr-d/codeph ph codeph" > Device< / code > 进一步细分成了 3 个层级: < code class = "+ topic/ph pr-d/codeph ph codeph" > Configuration< / code > 配置、
< code class = "+ topic/ph pr-d/codeph ph codeph" > Interface< / code > 接口、 < code class = "+ topic/ph pr-d/codeph ph codeph" > Endpoint< / code > 端点。< / p >
< p class = "- topic/p p" data-ofbid = "d280064e47__20250121171751" > USB Core 为其中两个层次提供了 < code class = "+ topic/ph pr-d/codeph ph codeph" > Device + Driver< / code > 的设备驱动模型,这两个层次分别是 < code class = "+ topic/ph pr-d/codeph ph codeph" > USB
Device Layer< / code > 和 < code class = "+ topic/ph pr-d/codeph ph codeph" > USB Interface Layer< / code > 层,一个 < code class = "+ topic/ph pr-d/codeph ph codeph" > USB
Device< / code > 包含一个或多个 < code class = "+ topic/ph pr-d/codeph ph codeph" > USB Interface< / code > 。其中:< / p >
< ul class = "- topic/ul ul" id = "usb_host_core__ul_hvy_tnz_21c" data-ofbid = "usb_host_core__ul_hvy_tnz_21c" > < li class = "- topic/li li" data-ofbid = "d280064e66__20250121171751" >
< p class = "- topic/p p" data-ofbid = "d280064e68__20250121171751" > < code class = "+ topic/ph pr-d/codeph ph codeph" > USB Device Layer< / code > 层。这一层的 < code class = "+ topic/ph pr-d/codeph ph codeph" > Device< / code > 由
< code class = "+ topic/ph pr-d/codeph ph codeph" > Hub< / code > 创建, < code class = "+ topic/ph pr-d/codeph ph codeph" > Hub< / code > 本身也是一种 < code class = "+ topic/ph pr-d/codeph ph codeph" > USB
Device< / code > 。这一层的 < code class = "+ topic/ph pr-d/codeph ph codeph" > Driver< / code > 完成的功能非常简单,基本就是帮
< code class = "+ topic/ph pr-d/codeph ph codeph" > USB Device< / code > 创建其包含的所有子 < code class = "+ topic/ph pr-d/codeph ph codeph" > USB Interface< / code > 的
< code class = "+ topic/ph pr-d/codeph ph codeph" > Device< / code > ,大部分场景下都是使用
< code class = "+ topic/ph pr-d/codeph ph codeph" > usb_generic_driver< / code > 。< / p >
< / li > < li class = "- topic/li li" data-ofbid = "d280064e101__20250121171751" >
< p class = "- topic/p p" data-ofbid = "d280064e103__20250121171751" > < code class = "+ topic/ph pr-d/codeph ph codeph" > USB Interface Layer< / code > 层。这一层的 < code class = "+ topic/ph pr-d/codeph ph codeph" > Device< / code > 由上一级
< code class = "+ topic/ph pr-d/codeph ph codeph" > USB Device< / code > 在驱动 probe() 时创建。而这一层的
< code class = "+ topic/ph pr-d/codeph ph codeph" > Driver< / code > 就是普通的业务 Usb 驱动,即 Usb 协议中所说的 < code class = "+ topic/ph pr-d/codeph ph codeph" > Client
Software< / code > 。< / p >
< / li > < / ul >
< / section > < section class = "- topic/section section" id = "usb_host_core__section_ivy_tnz_21c" data-ofbid = "usb_host_core__section_ivy_tnz_21c" > < h2 class = "- topic/title title sectiontitle" > URB (USB Request Block)< / h2 >
< div class = "- topic/p p" data-ofbid = "d280064e126__20250121171751" > < br / > < div class = "imagecenter" > < img class = "- topic/image image imagecenter" id = "usb_host_core__image_jvy_tnz_21c" src = "../../../images/usb/usb_host_urb.png" alt = "image2" / > < / div > < br / > < / div >
< p class = "- topic/p p" data-ofbid = "d280064e131__20250121171751" > USB Core 除了提供上一节描述的设备驱动模型以外,另一个重要的作用就是要给 < code class = "+ topic/ph pr-d/codeph ph codeph" > USB Interface< / code > Driver 提供读写
USB 数据的 API, 这一任务是围绕着 < code class = "+ topic/ph pr-d/codeph ph codeph" > USB Request Block< / code > 来完成的。< / p >
< p class = "- topic/p p" data-ofbid = "d280064e140__20250121171751" > < code class = "+ topic/ph pr-d/codeph ph codeph" > USB Interface< / code > Driver 适配成功以后,会从配置信息中获取到当前 Interface 包含了多少个
< code class = "+ topic/ph pr-d/codeph ph codeph" > Endpoint< / code > ,以及每个 < code class = "+ topic/ph pr-d/codeph ph codeph" > Endpoint< / code > 的地址、传输类型、最大包长等其他信息。
< code class = "+ topic/ph pr-d/codeph ph codeph" > Endpoint< / code > 是 USB 总线传输中最小的 < code class = "+ topic/ph pr-d/codeph ph codeph" > 寻址单位< / code > , Interface Driver
利用对几个 < code class = "+ topic/ph pr-d/codeph ph codeph" > Endpoint< / code > 的读写来驱动具体的设备功能。< / p >
< p class = "- topic/p p" data-ofbid = "d280064e160__20250121171751" > 对某个 < code class = "+ topic/ph pr-d/codeph ph codeph" > Endpoint< / code > 发起一次读写操作,具体工作使用 < code class = "+ topic/ph pr-d/codeph ph codeph" > struct urb< / code >
数据结构来承担。< / p >
< p class = "- topic/p p" data-ofbid = "d280064e170__20250121171751" > 以下是一个对 < code class = "+ topic/ph pr-d/codeph ph codeph" > Endpoint 0< / code > 使用 urb 发起读写的一个简单实例:< / p >
< pre class = "+ topic/pre pr-d/codeblock pre codeblock language-c" id = "usb_host_core__pre_kvy_tnz_21c" data-ofbid = "usb_host_core__pre_kvy_tnz_21c" > < strong class = "hl-keyword" > static< / strong > < strong class = "hl-keyword" > int< / strong > usb_internal_control_msg(< strong class = "hl-keyword" > struct< / strong > usb_device *usb_dev,
< strong class = "hl-keyword" > unsigned< / strong > < strong class = "hl-keyword" > int< / strong > pipe,
< strong class = "hl-keyword" > struct< / strong > usb_ctrlrequest *cmd,
< strong class = "hl-keyword" > void< / strong > *data, < strong class = "hl-keyword" > int< / strong > len, < strong class = "hl-keyword" > int< / strong > timeout)
{
< strong class = "hl-keyword" > struct< / strong > urb *urb;
< strong class = "hl-keyword" > int< / strong > retv;
< strong class = "hl-keyword" > int< / strong > length;
< em class = "hl-comment" > /* (1) 分配一个 urb 内存空间 */< / em >
urb = usb_alloc_urb(< span class = "hl-number" > 0< / span > , GFP_NOIO);
< strong class = "hl-keyword" > if< / strong > (!urb)
< strong class = "hl-keyword" > return< / strong > -ENOMEM;
< em class = "hl-comment" > /* (2) 填充 urb 内容,最核心的有 3 方面:
1、总线地址: Device Num + Endpoint Num
2、数据: data + len
3、回调函数: usb_api_blocking_completion
*/< / em >
usb_fill_control_urb(urb, usb_dev, pipe, (< strong class = "hl-keyword" > unsigned< / strong > < strong class = "hl-keyword" > char< / strong > *)cmd, data,
len, usb_api_blocking_completion, NULL);
< em class = "hl-comment" > /* (3) 发送 urb 请求,并且等待请求完成 */< / em >
retv = usb_start_wait_urb(urb, timeout, & length);
< strong class = "hl-keyword" > if< / strong > (retv < < span class = "hl-number" > 0< / span > )
< strong class = "hl-keyword" > return< / strong > retv;
< strong class = "hl-keyword" > else< / strong >
< strong class = "hl-keyword" > return< / strong > length;
}
↓
< strong class = "hl-keyword" > static< / strong > < strong class = "hl-keyword" > int< / strong > usb_start_wait_urb(< strong class = "hl-keyword" > struct< / strong > urb *urb, < strong class = "hl-keyword" > int< / strong > timeout, < strong class = "hl-keyword" > int< / strong > *actual_length)
{
< strong class = "hl-keyword" > struct< / strong > api_context ctx;
< strong class = "hl-keyword" > unsigned< / strong > < strong class = "hl-keyword" > long< / strong > expire;
< strong class = "hl-keyword" > int< / strong > retval;
init_completion(& ctx.done);
urb-> context = & ctx;
urb-> actual_length = < span class = "hl-number" > 0< / span > ;
< em class = "hl-comment" > /* (3.1) 把 urb 请求挂载到 hcd 的队列当中 */< / em >
retval = usb_submit_urb(urb, GFP_NOIO);
< strong class = "hl-keyword" > if< / strong > (unlikely(retval))
< strong class = "hl-keyword" > goto< / strong > out;
expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT;
< em class = "hl-comment" > /* (3.2) 当 urb 执行完成后,首先会调用 urb 的回调函数,然后会发送 completion 信号解除这里的阻塞 */< / em >
< strong class = "hl-keyword" > if< / strong > (!wait_for_completion_timeout(& ctx.done, expire)) {
usb_kill_urb(urb);
retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status);
dev_dbg(& urb-> dev-> dev,
< span class = "hl-string" > "%s timed out on ep%d%s len=%u/%u\n"< / span > ,
current-> comm,
usb_endpoint_num(& urb-> ep-> desc),
usb_urb_dir_in(urb) ? < span class = "hl-string" > "in"< / span > : < span class = "hl-string" > "out"< / span > ,
urb-> actual_length,
urb-> transfer_buffer_length);
} < strong class = "hl-keyword" > else< / strong >
retval = ctx.status;
out:
< strong class = "hl-keyword" > if< / strong > (actual_length)
*actual_length = urb-> actual_length;
usb_free_urb(urb);
< strong class = "hl-keyword" > return< / strong > retval;
}
< / pre >
< / section > < section class = "- topic/section section" id = "usb_host_core__section_lvy_tnz_21c" data-ofbid = "usb_host_core__section_lvy_tnz_21c" > < h2 class = "- topic/title title sectiontitle" > Normal Device urb_enqueue< / h2 >
< p class = "- topic/p p" data-ofbid = "d280064e184__20250121171751" > 对普通的 Usb device 来说, urb 最后会提交到 Host Controller 的收发队列上面,由 HC 完成实际的 USB 传输:< / p >
< pre class = "+ topic/pre pr-d/codeblock pre codeblock language-c" id = "usb_host_core__pre_mvy_tnz_21c" data-ofbid = "usb_host_core__pre_mvy_tnz_21c" > usb_submit_urb() → usb_hcd_submit_urb():
< strong class = "hl-keyword" > int< / strong > usb_hcd_submit_urb (< strong class = "hl-keyword" > struct< / strong > urb *urb, gfp_t mem_flags)
{
< em class = "hl-comment" > /* (1) 如果是 roothub 走特殊的路径 */< / em >
< strong class = "hl-keyword" > if< / strong > (is_root_hub(urb-> dev)) {
status = rh_urb_enqueue(hcd, urb);
< em class = "hl-comment" > /* (2) 如果是普通 device 调用对应的 hcd 的 urb_enqueue() 函数 */< / em >
} < strong class = "hl-keyword" > else< / strong > {
status = map_urb_for_dma(hcd, urb, mem_flags);
< strong class = "hl-keyword" > if< / strong > (likely(status == < span class = "hl-number" > 0< / span > )) {
status = hcd-> driver-> urb_enqueue(hcd, urb, mem_flags);
< strong class = "hl-keyword" > if< / strong > (unlikely(status))
unmap_urb_for_dma(hcd, urb);
}
}
}
< / pre >
< / section > < section class = "- topic/section section" id = "usb_host_core__section_nvy_tnz_21c" data-ofbid = "usb_host_core__section_nvy_tnz_21c" > < h2 class = "- topic/title title sectiontitle" > 7.12.5.1.2.2. Roothub Device urb_enqueue< / h2 >
< p class = "- topic/p p" data-ofbid = "d280064e195__20250121171751" > 特别需要注意的是 roothub 它是一个虚拟的 usb device, 实际上它并不在 usb 总线上而是在 host 内部,所以相应的 urb 需要特殊处理,而不能使用
hcd 把数据发送到 Usb 总线上去。< / p >
< pre class = "+ topic/pre pr-d/codeblock pre codeblock language-c" id = "usb_host_core__pre_ovy_tnz_21c" data-ofbid = "usb_host_core__pre_ovy_tnz_21c" > usb_submit_urb() → usb_hcd_submit_urb() → rh_urb_enqueue():
< strong class = "hl-keyword" > static< / strong > < strong class = "hl-keyword" > int< / strong > rh_urb_enqueue (< strong class = "hl-keyword" > struct< / strong > usb_hcd *hcd, < strong class = "hl-keyword" > struct< / strong > urb *urb)
{
< em class = "hl-comment" > /* (1) 对于 int 类型的数据,被挂载到 hcd-> status_urb 指针上面
通常 roothub 驱动用这个 urb 来查询 roothub 的端口状态
*/< / em >
< strong class = "hl-keyword" > if< / strong > (usb_endpoint_xfer_int(& urb-> ep-> desc))
< strong class = "hl-keyword" > return< / strong > rh_queue_status (hcd, urb);
< em class = "hl-comment" > /* (2) 对于 control 类型的数据,是想读取 roothub ep0 上的配置信息
使用软件来模拟这类操作的响应
*/< / em >
< strong class = "hl-keyword" > if< / strong > (usb_endpoint_xfer_control(& urb-> ep-> desc))
< strong class = "hl-keyword" > return< / strong > rh_call_control (hcd, urb);
< strong class = "hl-keyword" > return< / strong > -EINVAL;
}
|→
< strong class = "hl-keyword" > static< / strong > < strong class = "hl-keyword" > int< / strong > rh_queue_status (< strong class = "hl-keyword" > struct< / strong > usb_hcd *hcd, < strong class = "hl-keyword" > struct< / strong > urb *urb)
{
< em class = "hl-comment" > /* (1.1) 将 urb 挂载到对应的 ep 链表中 */< / em >
retval = usb_hcd_link_urb_to_ep(hcd, urb);
< strong class = "hl-keyword" > if< / strong > (retval)
< strong class = "hl-keyword" > goto< / strong > done;
< em class = "hl-comment" > /* (1.2) 将 urb 赋值给 hcd-> status_urb
在 hcd 驱动中,会通过这些接口来通知 roothub 的端口状态变化
*/< / em >
hcd-> status_urb = urb;
urb-> hcpriv = hcd; < em class = "hl-comment" > /* indicate it's queued */< / em >
< strong class = "hl-keyword" > if< / strong > (!hcd-> uses_new_polling)
mod_timer(& hcd-> rh_timer, (jiffies/(HZ/< span class = "hl-number" > 4< / span > ) + < span class = "hl-number" > 1< / span > ) * (HZ/< span class = "hl-number" > 4< / span > ));
}
|→
< strong class = "hl-keyword" > static< / strong > < strong class = "hl-keyword" > int< / strong > rh_call_control (< strong class = "hl-keyword" > struct< / strong > usb_hcd *hcd, < strong class = "hl-keyword" > struct< / strong > urb *urb)
{
< em class = "hl-comment" > /* (2.1) 软件模拟对 roothub 配置读写的响应 */< / em >
}< / pre >
< / section > < / div > < / article > < / main > < / div >
< / div >
< nav role = "navigation" id = "wh_topic_toc" aria-label = "On this page" class = "col-lg-2 d-none d-lg-block navbar d-print-none" >
< div id = "wh_topic_toc_content" >
< div class = " wh_topic_toc " > < div class = "wh_topic_label" > 在本页上< / div > < ul > < li class = "section-item" > < div class = "section-title" > < a href = "#usb_host_core__section_fvy_tnz_21c" data-tocid = "usb_host_core__section_fvy_tnz_21c" > Layer< / a > < / div > < / li > < li class = "section-item" > < div class = "section-title" > < a href = "#usb_host_core__section_ivy_tnz_21c" data-tocid = "usb_host_core__section_ivy_tnz_21c" > URB (USB Request Block)< / a > < / div > < / li > < li class = "section-item" > < div class = "section-title" > < a href = "#usb_host_core__section_lvy_tnz_21c" data-tocid = "usb_host_core__section_lvy_tnz_21c" > Normal Device urb_enqueue< / a > < / div > < / li > < li class = "section-item" > < div class = "section-title" > < a href = "#usb_host_core__section_nvy_tnz_21c" data-tocid = "usb_host_core__section_nvy_tnz_21c" > 7.12.5.1.2.2. Roothub Device urb_enqueue< / a > < / div > < / li > < / ul > < / div >
< / div >
< / nav >
< / div >
< / div >
< / div >
< footer class = "navbar navbar-default wh_footer" >
< div class = " footer-container mx-auto " >
< title > footer def< / title >
< style > < ! - -
.p1 {
font-family: FangZhengShuSong, Times, serif;
}
.p2 {
font-family: Arial, Helvetica, sans-serif;
}
.p3 {
font-family: "Lucida Console", "Courier New", monospace;
}
-->< / style >
< div class = "webhelp.fragment.footer" >
< p class = "p1" > Copyright © 2019-2024 广东匠芯创科技有限公司. All rights reserved.< / p >
< / div > < div >
< div class = "generation_time" >
Update Time: 2025-01-21
< / div >
< / div >
< / div >
< / footer >
< div id = "go2top" class = "d-print-none" >
< span class = "oxy-icon oxy-icon-up" > < / span >
< / div >
< div id = "modal_img_large" class = "modal" >
< span class = "close oxy-icon oxy-icon-remove" > < / span >
< div id = "modal_img_container" > < / div >
< div id = "caption" > < / div >
< / div >
< script src = "${pd}/publishing/publishing-styles-AIC-template/js/custom.js" defer = "defer" > < / script >
< / body >
2025-01-23 16:37:00 +08:00
< / html >