• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Combo解决方案之ASR芯片移植案例
2
3本方案基于OpenHarmony LiteOS-M内核,使用ASR582X芯片的[DEV.WIFI.A开发板](https://gitee.com/openharmony/device_board_lango)进行开发移植。作为典型的IOT Combo(Wi-Fi+BLE)解决方案,本文章介绍ASR582X的适配过程。
4
5## 编译移植
6
7### 目录规划
8
9本方案的目录结构使用[Board和Soc解耦的思路](https://gitee.com/openharmony-sig/sig-content/blob/master/devboard/docs/board-soc-arch-design.md)10
11```
12device
13├── board                                --- 单板厂商目录
14│   └── lango                            --- 单板厂商名字:朗国
15│       └── dev_wifi_a                   --- 单板名:DEV.WIFI.A
16└── soc                                  --- SoC厂商目录
17    └── asrmicro                         --- SoC厂商名字:翱捷科技
18        └── asr582x                      --- SoC Series名:ASR582X系列芯片
19```
20
21产品样例目录规划为:
22
23```
24vendor
25└── asrmicro                             --- 开发产品样例厂商目录,翱捷科技的产品样例
26    ├── wifi_demo                        --- 产品名字:Wi-Fi样例代码
27    └── xts_demo                         --- 产品名字: XTS测试样例
28```
29
30### 产品定义
31
32以`vendor/asrmicro/wifi_demo`为例,这里描述了产品使用的内核、单板、子系统等信息。其中,内核、单板型号、单板厂商需要提前规划好,也是预编译指令(`hb set`)所关注的。这里填入的信息与规划的目录相对应。例如:
33
34```
35{
36    "product_name": "wifi_demo",          --- 产品名
37    "type": "mini",                       --- 系统类型: mini
38    "version": "3.0",                     --- 系统版本: 3.0
39    "device_company": "lango",            --- 单板厂商:lango
40    "board": "dev_wifi_a",                --- 单板名:dev_wifi_a
41    "kernel_type": "liteos_m",            --- 内核类型:liteos_m
42    "kernel_version": "3.0.0",            --- 内核版本:3.0.0
43    "subsystems": []                      --- 子系统
44}
45```
46这里的device_company和board用于关联出//device/board/<device_company>/\<board\>目录。
47
48### 单板配置
49
50在关联到的\<board\>目录下,以`device/board/lango/dev_wifi_a`为例,需要在liteos_m目录下放置config.gni文件,这个配置文件用于描述该单板的信息,包括CPU、toolchain、kernel、compile flags等。例如:
51
52```
53# 内核类型。
54kernel_type = "liteos_m"
55
56# 内核版本。
57kernel_version = "3.0.0"
58
59# 单板CPU类型。
60board_cpu = "cortex-m4"
61
62# 工具链,这里使用arm-none-eabi。
63board_toolchain = "arm-none-eabi"
64
65# 工具链路径,可以使用系统路径,填"",也可以自定义,如下:
66board_toolchain_path = rebase_path("//device/soc/asrmicro/gcc/gcc-arm-none-eabi/Linux64/bin")
67
68# 单板相关的编译参数。
69board_cflags = []
70
71# 单板相关的链接参数。
72board_ld_flags = []
73
74# 单板相关的头文件。
75board_include_dirs = []
76```
77
78### 预编译
79
80在正确配置好产品的目录、产品定义、单板配置后,在工程根目录下输入预编译指令`hb set`,在显示的列表中就可以找到相关的产品。
81
82![ohos_config.json](figures/asr582x_ohos_config.png)
83
84选择好产品后,输入回车就会在根目录下自动生成`ohos_config.json`文件,这里会将要编译的产品信息列出。
85
86
87## 内核移植
88
89### Kconfig适配
90
91在//kernel/liteos_m的编译中,需要在相应的单板以及SoC目录下使用`Kconfig`文件进行索引。
92
93单板目录的`Kconfig`,以`//device/board/lango`为例:
94```
95├── dev_wifi_a                                   --- dev_wifi_a单板配置目录
96│   ├── Kconfig.liteos_m.board                   --- 单板的配置选项
97│   ├── Kconfig.liteos_m.defconfig.board         --- 单板的默认配置项
98│   └── liteos_m
99│       └── config.gni                           --- 单板的配置文件
100├── Kconfig.liteos_m.boards                      --- 单板厂商下Boards配置信息
101└── Kconfig.liteos_m.defconfig.boards            --- 单板厂商下Boards默认配置信息
102```
103
104在 `dev_wifi_a/Kconfig.liteos_m.board`中,配置只有SOC_ASR5822S被选后,BOARD_DEV_WIFI_A才可被选:
105
106```
107config BOARD_DEV_WIFI_A
108    bool "select board DEV_WIFI_A"
109    depends on SOC_ASR5822S
110```
111
112SoC目录的`Kconfig`,以`//device/soc/asrmicro`为例:
113
114```
115├── asr582x                                      --- ASR582X系列
116│   ├── Kconfig.liteos_m.defconfig.asr5822s      --- ASR5822S芯片默认配置
117│   ├── Kconfig.liteos_m.defconfig.series        --- ASR582X系列默认配置
118│   ├── Kconfig.liteos_m.series                  --- ASR582X系列配置
119│   └── Kconfig.liteos_m.soc                     --- ASR582X芯片配置
120├── Kconfig.liteos_m.defconfig                   --- SoC默认配置
121├── Kconfig.liteos_m.series                      --- Series配置
122└── Kconfig.liteos_m.soc                         --- SoC配置
123```
124
125asr582x/Kconfig.liteos_m.series中:
126
127```
128config SOC_SERIES_ASR582X
129    bool "ASR582X Series"
130    select ARM
131    select SOC_COMPANY_ASRMICRO              --- 选择 SOC_COMPANY_ASRMICRO
132    select CPU_CORTEX_M4
133    help
134        Enable support for ASR582X series
135```
136
137只有选择了 SOC_SERIES_ASR582X,在 asr582x/Kconfig.liteos_m.soc中才可以选择SOC_ASR5822S:
138
139```
140choice
141    prompt "ASR582X series SoC"
142    depends on SOC_SERIES_ASR582X
143
144config SOC_ASR5822S                         --- 选择 SOC_ASR5822S
145    bool "SoC ASR5822S"
146
147endchoice
148```
149
150综上所述,要编译单板BOARD_DEV_WIFI_A,则要分别选中:SOC_COMPANY_ASRMICRO、SOC_SERIES_ASR582X、SOC_ASR5822S,可以在`kernel/liteos_m`中执行`make menuconfig`进行选择配置。
151
152![asr5822s_select.json](figures/asr5822s_select.png)
153
154配置后的文件会默认保存在`//vendor/asrmicro/wifi_demo/kernel_configs/debug.config`,也可以直接填写debug.config155
156```
157LOSCFG_BOARD_DEV_WIFI_A=y
158LOSCFG_SOC_COMPANY_ASRMICRO=y
159LOSCFG_SOC_SERIES_ASR582X=y
160LOSCFG_SOC_ASR5822S=y
161```
162
163### 模块化编译
164
165`Board`和`SoC`的编译采用模块化的编译方法,从`kernel/liteos_m/BUILD.gn`开始逐级向下递增。本方案的适配过程如下:
166
1671. 在`//device/board/lango`中新建文件BUILD.gn,新增内容如下:
168
169   ```
170   if (ohos_kernel_type == "liteos_m") {
171     import("//kernel/liteos_m/liteos.gni")
172     module_name = get_path_info(rebase_path("."), "name")
173     module_group(module_name) {
174       modules = [
175         "dev_wifi_a",                     # 单板模块。
176         "hcs",                            # hcs文件的对应模块。
177       ]
178     }
179   }
180   ```
181
182   在上述BUILD.gn中,dev_wifi_a以及hcs即是按目录层级组织的模块名。
183
1842. 在`//device/soc/asrmicro`中,使用同样的方法,新建文件BUILD.gn,按目录层级组织,新增内容如下:
185
186   ```
187   if (ohos_kernel_type == "liteos_m") {
188     import("//kernel/liteos_m/liteos.gni")
189     module_name = get_path_info(rebase_path("."), "name")
190     module_group(module_name) {
191       modules = [
192         "asr582x",
193       ]
194     }
195   }
196   ```
197
1983. 在`//device/soc/asrmicro`各个层级模块下,同样新增文件BUILD.gn,将该层级模块加入编译,以`//device/soc/asrmicro/asr582x/liteos_m/sdk/startup/BUILD.gn`为例:
199
200   ```
201   import("//kernel/liteos_m/liteos.gni")
202
203   config("public") {
204     include_dirs = [ "." ]                 # 公共头文件。
205   }
206
207   kernel_module("asr_startup") {           # 编译的模块。
208     sources = [                            # 编译的源文件.
209         "startup.c",
210         "board.c",
211         "startup_cm4.S",
212     ]
213
214     include_dirs = [                       # 模块内使用到的头文件。
215       "...",
216     ]
217   }
218   ```
219
2204. 为了组织链接以及一些编译选项,在`//device/soc/asrmicro/asr582x/liteos_m/sdk/config/BUILD.gn`下的config("public")填入了相应的参数:
221
222   ```
223   config("public") {
224     include_dirs = []                       # 公共头文件。
225     ldflags = []                            # 链接参数,包括ld文件。
226     libs = []                               # 链接库。
227     defines = []                            # 定义。
228   ```
229
230   ![](../public_sys-resources/icon-note.gif) **说明:**
231	建议公共的参数选项以及头文件不在各个组件中重复填写。
232
2335. 为了组织一些产品侧的应用,本方案在vendor相应的config.json加入了相应的list来组织,以`//vendor/asrmicro/wifi_demo/config.json`为例,在config.json增加对应的list:
234   ```
235   "tests_list": [                       --- demo list
236     {
237       "enable": "true",                 --- list开关
238       "test_modules": [
239         "example",                      --- OS基础demo
240         "wifi_test"                     --- Wi-Fi demo
241       ]
242     }
243   ]
244   ```
245
246   这里将demo作为了模块来管理,开启/关闭某个demo,在tests_list中增减项即可。tests_list在gn中可以直接被读取,需要在`//device/board/lango/dev_wifi_a/liteos_m/config.gni`加入以下内容:
247
248   ```
249   product_conf = read_file("${product_path}/config.json", "json")
250   product_name = product_conf.product_name
251   tests_list = product_conf.tests_list
252   ```
253
254   读取list后即可在相应的链接选项上加入相关的组件库,需要在`//device/soc/asrmicro/asr582x/liteos_m/sdk/config/BUILD.gn`加入以下内容:
255
256   ```
257   foreach(test_item, tests_list) {
258       test_enable = test_item.enable
259       if(test_enable == "true")
260       {
261         foreach(test_module, test_item.test_modules) {
262         ldflags += [ "-l${test_module}" ]
263         }
264       }
265   }
266   ```
267
268### C库适配
269
270为了整个系统不区分用户态内核态,上层组件与内核共用一套基于musl的C库,本方案使用musl C,三方库见`//third_party/musl/porting/liteos_m/kernel/BUILD.gn`。
271
272kernel另外对malloc相应的code进行了改造适配,适配文件见`//kernel/liteos_m/kal/libc/musl/porting/src/malloc.c`。
273
274在本方案中,printf相关的接口使用开源代码实现,适配文件见 `//device/soc/asrmicro/asr582x/liteos_m/sdk/drivers/platform/system/printf-stdarg.c`。
275
276为了满足printf相关接口的链接调用,需要在`//device/board/lango/dev_wifi_a/liteos_m/config.gni`的新增这些函数的wrap链接:
277
278```
279board_ld_flags += [
280  "-Wl,--wrap=printf",
281  "-Wl,--wrap=sprintf",
282  "-Wl,--wrap=snprintf",
283  "-Wl,--wrap=vprintf",
284  "-Wl,--wrap=vsprintf",
285  "-Wl,--wrap=vsnprintf",
286]
287```
288### shell适配
289
290为了方便调试,本方案集成了内核的shell组件,可以在make menuconfig中的Debug中选中 Enable Shell,或者在`//vendor/asrmicro/wifi_demo/kernel_configs/debug.config`文件中填入LOSCFG_SHELL=y
291shell组件需要进行初始化,可参考`device/soc/asrmicro/asr582x/liteos_m/sdk/startup/board.c`:
292
293```
294ret = LosShellInit();
295if (ret != LOS_OK) {
296    printf("LosShellInit failed! ERROR: 0x%x\n", ret);
297}
298ret = OsShellInit();
299if (ret != LOS_OK) {
300    printf("OsShellInit failed! ERROR: 0x%x\n", ret);
301}
302```
303
304在初始化之后,每个shell命令需要进行注册,例如:`vendor/asrmicro/wifi_demo/tests/wifi/wifi_app.c`:
305
306```
307osCmdReg(CMD_TYPE_STD, "wifi_open", 0, (CMD_CBK_FUNC)ap_conn_func);    // 连接AP的指令,这里可以带参。
308osCmdReg(CMD_TYPE_EX, "wifi_close", 0, (CMD_CBK_FUNC)ap_close_func);   // 断开指令。
309```
310
311### 内核启动适配
312
313单板进入到main函数后,首先会进行单板初始化,然后需要注册中断,之后再进行内核的初始化和调度。
314注册中断,可参考`//device/soc/asrmicro/asr582x/liteos_m/sdk/startup/board.c`:
315
316```
317ArchHwiCreate(UART1_IRQn,configLIBRARY_NORMAL_INTERRUPT_PRIORITY,0,UART1_IRQHandler,0);   // UART中断。
318ArchHwiCreate(GPIO_IRQn,configLIBRARY_NORMAL_INTERRUPT_PRIORITY,0,GPIO_IRQHandler,0);     // GPIO中断。
319```
320
321内核初始化示例如下:
322```
323osStatus_t ret = osKernelInitialize();                                                    // 内核初始化。
324
325if(ret == osOK)
326{
327    threadId = osThreadNew((osThreadFunc_t)sys_init,NULL,&g_main_task);                   // 创建init线程。
328
329    if(threadId!=NULL)
330    {
331        osKernelStart();                                                                  // 线程调度。
332    }
333}
334```
335
336在`sys_init`中,需要对OpenHarmony的系统组件进行初始化:
337
338```
339...
340DeviceManagerStart();           // HDF初始化。
341
342OHOS_SystemInit();              // OpenHarmony系统组件初始化。
343....
344```
345
346### HDF驱动框架适配
347
348HDF驱动框架提供了一套应用访问硬件的统一接口,可以简化应用开发,添加HDF组件需要在`//vendor/asrmicro/wifi_demo/kernel_configs/debug.config`添加:
349
350```
351LOSCFG_DRIVERS_HDF=y
352LOSCFG_DRIVERS_HDF_PLATFORM=y
353```
354
355同时需在board中新增对应开发板硬件配置描述文件,位于`//device/board/lango/hcs`。本案例以GPIO以及UART为例,移植过程如下:
356
357#### GPIO适配
358
3591. 芯片驱动适配文件位于`//drivers/hdf_core/adapter/platform`目录,在gpio目录增加gpio_asr.c文件,在BUILD.gn中增加新增的驱动文件编译条件:
360
361   ```
362   if (defined(LOSCFG_SOC_COMPANY_ASRMICRO)) {
363     sources += [ "gpio_asr.c" ]
364   }
365   ```
366
3672. gpio_asr.c中驱动描述文件如下:
368
369   ```
370   struct HdfDriverEntry g_GpioDriverEntry = {
371       .moduleVersion = 1,
372       .moduleName = "ASR_GPIO_MODULE_HDF",
373       .Init = GpioDriverInit,
374       .Release = GpioDriverRelease,
375   };
376   HDF_INIT(g_GpioDriverEntry);
377   ```
378
3793. 在`//device/board/lango/hcs`添加gpio硬件描述信息文件gpio.hcs, 映射后的gpio0控制板卡上的可编程LED,gpio1对应用户按键,hcs内容如下:
380
381   ```
382   root {
383       platform {
384           gpio_config {
385               match_attr = "gpio_config";
386               pin = [0, 1];
387               // led3: GPIO9.
388               // user key: GPIO7.
389               realPin = [9, 7];
390               config = [5, 1];
391               pinNum = 2;
392           }
393       }
394   }
395   ```
396
3974. gpio.hcs的配置信息会在GpioDriverInit进行加载,并执行对应GPIO引脚的初始化。应用层控制LED灯和读取按键信息只需要以下简单的代码:
398
399   ```
400   int32_t GpioKeyIrqFunc(uint16_t gpio, void *data)
401   {
402       printf("user key %d pressed\n", gpio);
403   }
404   GpioSetIrq(1, OSAL_IRQF_TRIGGER_FALLING, GpioKeyIrqFunc, NULL);
405
406   GpioWrite(0, 0);
407   lega_rtos_delay_milliseconds(1000);
408   GpioWrite(0, 1);
409   ```
410
411#### UART适配
412
4131. 芯片驱动适配文件位于`//drivers/adapter/platform`目录,在uart目录增加uart_asr.cuart_asr.h文件,在BUILD.gn中增加新增的驱动文件编译条件:
414
415   ```
416   if (defined(LOSCFG_SOC_COMPANY_ASRMICRO)) {
417     sources += [ "uart_asr.c" ]
418   }
419   ```
420
4212. uart_asr.c中驱动描述文件如下:
422
423   ```
424   struct HdfDriverEntry g_hdfUartDevice = {
425       .moduleVersion = 1,
426       .moduleName = "HDF_PLATFORM_UART",
427       .Bind = HdfUartDeviceBind,
428       .Init = HdfUartDeviceInit,
429       .Release = HdfUartDeviceRelease,
430   };
431
432   HDF_INIT(g_hdfUartDevice);
433   ```
434
4353. 在`//device/board/lango/hcs`添加gpio硬件描述信息文件uart.hcs, hcs内容如下:
436
437   ```
438   controller_uart0 :: uart_controller {
439       match_attr = "asr582x_uart_0";
440       port = 0;                        /* UART_ID_0 */
441
442       pin_tx_pin = 0;                  /* IO_PIN_10 */
443       pin_tx_mux = 25;                 /* IO_MUX_2  */
444
445       pin_rx_pin = 1;                  /* IO_PIN_11 */
446       pin_rx_mux = 25;                 /* IO_MUX_2 */
447       tx_rx = 3;                       /* TX_RX MODE */
448   }
449   ```
450
4514. gpio.hcs的配置信息会在HdfUartDeviceInit进行加载,并执行对应串口引脚的初始化。应用层测试串口代码如下:
452
453   ```
454   DevHandle uart_handle = UartOpen(0);
455   UartSetBaud(uart_handle, 115200);
456   ...
457   attr.dataBits = UART_ATTR_DATABIT_8;
458   attr.parity = UART_ATTR_PARITY_NONE;
459   attr.stopBits = UART_ATTR_STOPBIT_1;
460   ret = UartSetAttribute(uart_handle, &attr);
461   ret = UartWrite(uart_handle, send_data, strlen(send_data));
462   ret = UartRead(uart_handle, recv_data, sizeof(recv_data) - 1);
463   ...
464   ```
465
466## OpenHarmony组件移植
467
468子系统的编译选项入口在相应产品config.json下,以下以`//vendor/asrmicro/wifi_demo/config.json`为例。
469
470### lwIP组件
471
472lwIP组件的源码在`//third_party/lwip`,OpenHarmony在kernel中做了定制化,`//kernel/liteos_m/components/net/lwip-2.1`,包括一些接口的重定义,结构体的重定义等。
473
474lwIP组件适配:
475
476lwIP是一个小型开源的TCP/IP协议栈,LiteOS-M已对开源lwIP做了适配和功能增强,lwIP代码分为两部分:
477
478
479- third_party/lwip目录下是lwIP开源代码,里面只做了少量的侵入式修改,为了适配增强功能。
480
481- kernel/liteos_m/components/net/lwip-2.1目录下是lwIP适配和功能增强代码,里面提供了lwIP的默认配置文件。
482
483
484如果需要使用lwIP组件,请按如下步骤适配:
485
486
4871. 在产品目录下新建一个目录用来存放产品的适配文件,如lwip_adapter。
488
4892. 在lwip_adapter目录下新建一个目录include,用来存放适配的头文件。
490
4913. 在include目录下新建目录lwip,并在lwip目录下新建头文件lwipopts.h,代码如下所示,如果默认配置不能满足产品使用,可自行根据产品使用情况修改配置,如关闭DHCP功能。
492
493   ```
494   #ifndef _LWIP_ADAPTER_LWIPOPTS_H_
495   #define _LWIP_ADAPTER_LWIPOPTS_H_
496
497   #include_next "lwip/lwipopts.h"
498
499   #undef LWIP_DHCP#define LWIP_DHCP                       0 // 关闭DHCP功能。
500
501   #endif /* _LWIP_ADAPTER_LWIPOPTS_H_ */
502   ```
503
5044. 将kernel/liteos_m/components/net/lwip-2.1目录下的BUILD.gn复制到lwip_adapter目录下,并按如下修改。
505
506   ```
507   import("//kernel/liteos_m/liteos.gni")
508   import("$LITEOSTHIRDPARTY/lwip/lwip.gni")
509   import("$LITEOSTOPDIR/components/net/lwip-2.1/lwip_porting.gni")
510   module_switch = defined(LOSCFG_NET_LWIP_SACK)
511   module_name = "lwip"kernel_module(module_name) {
512     sources = LWIP_PORTING_FILES + LWIPNOAPPSFILES - [ "$LWIPDIR/api/sockets.c" ]
513     include_dirs = [ "//utils/native/lite/include" ]
514   }
515   #添加新增加的适配头文件路径include。
516   config("public") {
517     include_dirs = [ "include" ] + LWIP_PORTING_INCLUDE_DIRS + LWIP_INCLUDE_DIRS
518   }
519   ```
520
5215. 在产品的配置文件(如config.json)中设置lwIP的编译路径,即步骤4中BUILD.gn的路径。
522
523   ```
524   {
525     "subsystem": "kernel",
526     "components": [
527       { "component": "liteos_m", "features":["ohos_kernel_liteos_m_lwip_path = \"//xxx/lwip_adapter\"" ] }
528     ]
529   },
530   ```
531
5326. 在产品的内核编译配置文件中,如kernel_config/debug.config,打开编译lwIP的开关。
533
534   ```
535   LOSCFG_NET_LWIP=y
536   ```
537
538本案例在config.json中设置lwIP的路径如下:
539
540   ```
541   "subsystem": "kernel",
542   "components": [
543     {
544       "component": "liteos_m",
545       "features": [
546         "ohos_kernel_liteos_m_lwip_path = \"//device/soc/asrmicro/asr582x/liteos_m/components/net/lwip-2.1\""
547       ]
548     }
549   ]
550   ```
551
552另外,需在内核编译配置文件kernel_config/debug.config中,打开编译lwIP的开关,如下:
553
554```
555LOSCFG_NET_LWIP=y
556```
557
558### security组件
559
560security需要在config.json中打开相应的选项,本案例移植了三方库中的mbedtls(`//third_party/mbedtls`)作为加密模块,选项配置如下:
561
562```
563"subsystem": "security",
564"components": [
565  { "component": "huks", "features":
566    [
567      ...
568      "ohos_security_huks_mbedtls_porting_path = \"//device/soc/asrmicro/asr582x/liteos_m/components/mbedtls\""
569    ]
570  }
571]
572```
573
574在上述目录中,需要对mbedtls做配置,可见`config/config_liteos_m.h`。需要注意的是,如果使用mbedtls的RNG的能力(比如dsoftbus组件在`//foundation/communication/dsoftbus/adapter/common/mbedtls/softbus_adapter_crypto.c`中有使用),要指定产生随机数的熵源。本案例使用了ASR582X的硬件随机数能力,需要打开如下宏定义:
575
576```
577#define MBEDTLS_ENTROPY_HARDWARE_ALT
578```
579
580打开此宏后,需要实现entropy_hardware_alt接口,可见`library/entropy_hardware_alt.c`。
581
582### wifi_lite组件
583
584wifi_lite组件的选项配置如下:
585
586```
587"subsystem": "communication",
588"components": [
589  { "component": "wifi_lite", "features":[] }
590  ]
591```
592
593与Wi-Fi有关的实现在`//device/soc/asrmicro/asr582x/liteos_m/sdk/hal/src/wifi_adapter.c`下。
594
595本案例也提供了使用wifi_lite相关接口的Demo,可见`//vendor/asrmicro/wifi_demo/tests/wifi/wifi_app.c`,这里提供了两个连接的测试指令:
596
597表 1 ASR Wi-Fi 连接指令
598
599| 指令         | 参数     | 说明     |
600|------------|--------|--------|
601| wifi_open  | sta [SSID] [KEY] | 连接路由指令,例如:wifi_open sta ASR_AP test123456。 |
602| wifi_close | 无      | 断开连接指令。   |
603
604### xts组件
605
606xts组件的适配,以`//vendor/asrmicro/xts_demo/config.json`为例,需要加入组件选项:
607
608```
609"subsystem": "xts",
610"components": [
611  { "component": "xts_acts", "features":
612    [
613      "enable_ohos_test_xts_acts_use_thirdparty_lwip = true"
614    ]
615  },
616  { "component": "xts_tools", "features":[] }
617]
618```
619
620另外,xts功能也使用了list来组织,可参考[模块化编译],在config.json文件中增减相应模块:
621
622```
623"xts_list": [
624  {
625    "enable": "true",
626    "xts_modules": [
627      "ActsKvStoreTest",
628      "ActsDfxFuncTest",
629      "ActsHieventLiteTest",
630      "ActsSamgrTest",
631      "ActsParameterTest",
632      "ActsWifiServiceTest",
633      "ActsWifiIotTest",
634      "ActsBootstrapTest"
635    ]
636  }
637],
638```
639
640### dsoftbus组件
641
642dsoftbus组件提供了设备间的发现连接、组网和传输能力,本方案以Wi-Fi设备间的软总线能力为例。
643
644依赖组件:lwIP组件、security组件、wifi_lite组件。
645
646前置条件:设备需先连接路由,所有的组网设备需在同一局域网中。
647
648dsoftbus组件的选项配置如下:
649
650```
651"subsystem": "communication",
652"components": [
653  { "component": "dsoftbus", "features":[] }
654  ]
655```
656
657在`//vendor/asrmicro/wifi_demo`下提供了dsoftbus的测试Demo,打开该功能需修改`//vendor/asrmicro/wifi_demo/tests/BUILD.gn`:
658
659```
660declare_args() {
661  asr_dsoftbus_test = true              # 打开dsoftbus demo编译。
662}
663```
664
665另外,需在`//vendor/asrmicro/wifi_demo/config.json`中添加dsoftbus_test模块:
666
667```
668"tests_list": [
669    {
670    "enable": "true",
671    "test_modules": [
672        "wifi_test",
673        "dsoftbus_test"                 # 打开dsoftbus_test模块。
674    ]
675    }
676]
677```
678
679dsoftbus组件的启动接口可参考`//vendor/asrmicro/wifi_demo/tests/dsoftbus/dsoftbus_app.c`:
680
681```
682InitSoftBusServer();
683```
684
685dsoftbus组件的运行需至少预留80KB RAM。如资源不够,可对其它地方进行剪裁。例如,可在以下文件修改lwIP组件:
686`//kernel_liteos_m/blob/master/components/net/lwip-2.1/porting/include/lwip/lwipopts.h`:
687
688```
689#define TCPIP_THREAD_STACKSIZE          0x2000              // 缩小TCPIP任务栈大小
690```
691
692在communication_dsoftbus仓中,加入了-fPIC编译选项,这样会让编译器产生与位置无关代码,并使用相对地址,但是在LiteOS-M核中使用的是静态库,不推荐使用。
693建议开发者手动注释-fPIC编译选项,后续会推进OpenHarmony统一规划此编译选项的开关。修改方法是在如下的四个文件中,找到"-fPIC"选项,并全部注释:
694
695`//foundation/communication/dsoftbus/core/common/BUILD.gn`
696
697`//foundation/communication/dsoftbus/core/frame/BUILD.gn`
698
699`//foundation/communication/dsoftbus/sdk/BUILD.gn`
700
701`//foundation/communication/dsoftbus/components/nstackx_mini/nstackx_ctrl/BUILD.gn`
702
703软总线的组网需要通过设备认证,在研发阶段,可以把认证跳过,先行调试组网以及传输能力,需将文件`//foundation/communication/dsoftbus/core/authentication/src/auth_manager.c`中的HandleReceiveDeviceId函数替换为如下实现:
704
705```
706void HandleReceiveDeviceId(AuthManager *auth, uint8_t *data)
707{
708    uint8_t tempKey[SESSION_KEY_LENGTH] = {0};
709    if (auth == NULL || data == NULL) {
710        SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "invalid parameter");
711        return;
712    }
713    if (AuthUnpackDeviceInfo(auth, data) != SOFTBUS_OK) {
714        SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "AuthUnpackDeviceInfo failed");
715        AuthHandleFail(auth, SOFTBUS_AUTH_UNPACK_DEVID_FAILED);
716        return;
717    }
718    if (auth->side == SERVER_SIDE_FLAG) {
719        if (EventInLooper(auth->authId) != SOFTBUS_OK) {
720            SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "auth EventInLooper failed");
721            AuthHandleFail(auth, SOFTBUS_MALLOC_ERR);
722            return;
723        }
724        if (AuthSyncDeviceUuid(auth) != SOFTBUS_OK) {
725            AuthHandleFail(auth, SOFTBUS_AUTH_SYNC_DEVID_FAILED);
726        }
727        (void)memset_s(tempKey, SESSION_KEY_LENGTH, 1, SESSION_KEY_LENGTH);
728        AuthOnSessionKeyReturned(auth->authId, tempKey, SESSION_KEY_LENGTH);
729        return;
730    }
731    //VerifyDeviceDevLvl(auth);                                            --- 这里注释认证过程
732    (void)memset_s(tempKey, SESSION_KEY_LENGTH, 1, SESSION_KEY_LENGTH);
733    AuthOnSessionKeyReturned(auth->authId, tempKey, SESSION_KEY_LENGTH);
734}
735```
736
737在正确配置并编译烧录后,设备使用wifi_open指令连接路由,连接成功后,设备会自动进行组网。如下为组网成功截图:
738
739![dsoftbus_join_LNN](figures/asr582x_dsoftbus_join_LNN.png)
740
741
742其它组件的适配过程与官方以及其它厂商的过程类似,不再赘述。
743
744## todo
745
746- 待支持BLE
747- 待丰富Wi-Fi测试指令