尝试给OpenHarmony4.0增加可以在动态库中使用的日志模块

尝试给OpenHarmony4.0增加可以在动态库中使用的日志模块


前言

最近在搞OpenHarmony4.0蓝牙模块的适配,最主要的工作就是在libbt_vendor.z.so这个库的编写修改,该库上承HDF驱动,下接内核驱动。

目前卡在了该库中对蓝牙设备进行相关操作的接口,需要增加日志打印进行调试。但OpenHarmony的hilog貌似在动态库中加的日志并不能通过hilog命令在串口或者HDC中进行打印,所以想再加一套单独的日志打印途径。


一、资源来源

OpenHarmony单模块welog打印机制

打算使用该内容进行测试使用。
https://gitee.com/itopen/module_code/tree/master

验证后发现基本按README.md的使用指导进行即可,但有些小细节需要自己摸索。

二、实践步骤

1.修改OH内核并编译

将gitee资源对应目录C/welog/driver的welog文件夹直接放到OH版本的内核驱动目录下,本文使用的是RISCV架构的OH4.0-RVBOOK版本,对应的目录为:

kernel/linux/rvbook-kernel/drivers/

其他版本的内核驱动目录比如:

kernel/linux/linux-5.10/drivers/

然后对该目录下的Kconfig和Makefile进行修改,因为有顺序影响,为了避免麻烦,所以建议将新增的内容直接放到对应文件的靠后位置。

Kconfig文件新增此行:

c 复制代码
source "drivers/welog/Kconfig"

Makefile文件新增此行

c 复制代码
obj-y               += welog/

修改保存后,删除OH版本out目录下的kernel和对应产品生成的images目录下的内核镜像,使用下面命令进行内核编译(有些产品不需要加"--no-prebuilt-sdk"选项):

./build.sh --product-name rvbook --ccache --no-prebuilt-sdk -T build_kernel

2.动态库增加welog打印

将gitee上include目录下的welog.h放到能被libbt_vendor调用到的对应目录(查看BUILD.gn即可),在需要加入之的.c文件中进行#include引用。修改该.c文件,比如op()代码增加welog打印。

根据welog.h的内容,发现此日志模块支持welog_err、welog_info、welog_debug三种模式,使用这些直接代替标准化格式输出的printf即可。

比如:

c 复制代码
static int op(bt_opcode_t opcode, void *param)
{
    welog_err("bluetooth op start!! %d", opcode);
    int retval = 0;

    switch (opcode) {
        case BT_OP_POWER_ON: // Power on the BT Controller.
            if (rtkbt_transtype & RTKBT_TRANS_UART) 
            {
                upio_set_bluetooth_power(UPIO_BT_POWER_OFF);
                usleep(20000L);
                welog_err("set power off and delay 200ms");
                upio_set_bluetooth_power(UPIO_BT_POWER_ON);
                welog_err("set power on and delay 00ms");
            }
            break;

        case BT_OP_POWER_OFF: // Power off the BT Controller.
            if (rtkbt_transtype & RTKBT_TRANS_UART) 
            {
                upio_set_bluetooth_power(UPIO_BT_POWER_OFF);
                usleep(20000L);
                welog_err("set power off and delay 200ms");
            }
            break;

        // Establish hci channels. it will be called after BT_OP_POWER_ON.
        case BT_OP_HCI_CHANNEL_OPEN: 
	    {
            welog_err("bluetooth open channel");
            if ((rtkbt_transtype & RTKBT_TRANS_UART) && (rtkbt_transtype & RTKBT_TRANS_H5)) 
            {
		        welog_err("bluetooth trans h5");
                int fd, idx;
                int(*fd_array)[] = (int(*)[])param;
                if (userial_vendor_open((tUSERIAL_CFG *)&userial_H5_cfg) != -1) {
                    retval = 1;
                }

                fd = userial_socket_open();
                if (fd != -1) 
                {
                    for (idx = 0; idx < HCI_MAX_CHANNEL; idx++) 
                    {
                        (*fd_array)[idx] = fd;
                    }
                } 
                else 
                {
                    retval = 0;
                }
            } 
            else if ((rtkbt_transtype & RTKBT_TRANS_UART) && (rtkbt_transtype & RTKBT_TRANS_H4)) 
            {
		        welog_err("bluetooth trans h4");
                /* retval contains numbers of open fd of HCI channels */
                int(*fd_array)[] = (int(*)[])param;
                int fd, idx;
                if (userial_vendor_open((tUSERIAL_CFG *)&userial_H4_cfg) != -1) 
                {
                    retval = 1;
                }
                fd = userial_socket_open();
                if (fd != -1) 
                {
                    for (idx = 0; idx < HCI_MAX_CHANNEL; idx++) 
                    {
                        (*fd_array)[idx] = fd;
                    }
                } else {
                    retval = 0;
                }
                /* retval contains numbers of open fd of HCI channels */
            } 
            else 
            {
                welog_err("bluetooth USB op for %d", opcode);
                int fd, idx = 0;
                int(*fd_array)[] = (int(*)[])param;
                for (idx = 0; idx < 10L; idx++) 
                {
                    if (userial_vendor_usb_open() != -1) 
                    {
                        retval = 1;
                        break;
                    }
                }
                fd = userial_socket_open();
                if (fd != -1) 
                {
                    for (idx = 0; idx < HCI_MAX_CHANNEL; idx++) 
                    {
                        (*fd_array)[idx] = fd;
                    }
                } 
                else 
                {
                    retval = 0;
                }
            }
        }
        break;

        // Close all the hci channels which is opened.
        case BT_OP_HCI_CHANNEL_CLOSE: 
        {
            userial_vendor_close();
        }
        break;

        // initialization the BT Controller. it will be called after
        // BT_OP_HCI_CHANNEL_OPEN. Controller Must call init_cb to notify the host
        // once it has been done.
        case BT_OP_INIT: 
        {
            welog_err("bluetooth start BT_OP_INIT");
            if (rtkbt_transtype & RTKBT_TRANS_UART) 
            {
                welog_err("rtkbt_transtype & RTKBT_TRANS_UART hw_config_start");
                hw_config_start(rtkbt_transtype);
            } 
            else 
            {
                welog_err("BT_OP_INIT else");
                int usb_info = 0;
                retval = userial_vendor_usb_ioctl(GET_USB_INFO, &usb_info);
                if (retval == -1) 
                {
                    welog_err("bluetooth get usb info fail");
                    return retval;
                } 
                else 
                {
                    welog_err("bluetooth hw_usb_config_start");
                    hw_usb_config_start(RTKBT_TRANS_H4, usb_info);
                }
            }
            RTK_btservice_init();
        }
        break;

        // Get the LPM idle timeout in milliseconds.
        case BT_OP_GET_LPM_TIMER: {
        }
        break;

        // Enable LPM mode on BT Controller.
        case BT_OP_LPM_ENABLE: {
        }
        break;

        // Disable LPM mode on BT Controller.
        case BT_OP_LPM_DISABLE: {
        }
        break;

        // Wakeup lock the BTC.
        case BT_OP_WAKEUP_LOCK: {
        }
        break;

        // Wakeup unlock the BTC.
        case BT_OP_WAKEUP_UNLOCK: {
        }
        break;

        // transmit event response to vendor lib.
        case BT_OP_EVENT_CALLBACK: {
            hw_process_event((HC_BT_HDR *)param);
        }
        break;
    }
    welog_err("bluetooth op return result:%d", retval);
    return retval;
}

编译对应目标或者直接正版本增量编译,使打印生效。

./build.sh --product-name rvbook --ccache --no-prebuilt-sdk

3.设备验证

编译完成后进行全镜像烧录。

设备启动后,通过串口或者HDC查看设备/dev目录下设备

此处还需要通过chomd修改welog驱动权限,否则日志功能不可用。

chmod -R 777 /dev/welog

阅读新增的日志驱动代码,可以发现新的模块日志将会被保存在/data/log/welog/welog.log中

之后在确保新增日志的接口被调用后,发现该目录并没有日志文件生成。此处应该是日志模块代码的一个小bug,代码并没有生成不存在的子目录

因此需要手动

mkdir /data/log/welog/

chmod -R 777 /data/log/welog/

又因为该OH内核不支持vim等命令创建新文件,因此使用HDC将welog.log放到该目录下

./hdc file send welog.log /data/log/welog/

然后运行相关模块的代码,使用命令

tail -f /data/log/welog/welog.log

监测日志变化即可。

./hdc shell mount -oremount,rw /

./hdc shell mount -oremount,rw /vendor

./hdc shell mkdir /data/log/welog/

./hdc file send .../images/welog.log /data/log/welog/

./hdc shell chmod -R 777 /data/log/welog/

打完收工

总结

需要知道HDC用法,linux内核的一些基本知识,OH的修改、编译、烧录、运行。

参考

https://blog.csdn.net/weixin_42135087/article/details/139903669

相关推荐
SameX4 小时前
HarmonyOS Next 安全生态构建与展望
前端·harmonyos
SameX4 小时前
HarmonyOS Next 打造智能家居安全系统实战
harmonyos
Random_index12 小时前
#Uniapp篇:支持纯血鸿蒙&发布&适配&UIUI
uni-app·harmonyos
鸿蒙自习室15 小时前
鸿蒙多线程开发——线程间数据通信对象02
ui·harmonyos·鸿蒙
SuperHeroWu717 小时前
【HarmonyOS】鸿蒙应用接入微博分享
华为·harmonyos·鸿蒙·微博·微博分享·微博sdk集成·sdk集成
zhangjr057520 小时前
【HarmonyOS Next】鸿蒙实用装饰器一览(一)
前端·harmonyos·arkts
诗歌难吟4641 天前
初识ArkUI
harmonyos
SameX1 天前
HarmonyOS Next 设备安全特性深度剖析学习
harmonyos
郭梧悠1 天前
HarmonyOS(57) UI性能优化
ui·性能优化·harmonyos
郝晨妤2 天前
鸿蒙原生应用开发元服务 元服务是什么?和App的关系?(保姆级步骤)
android·ios·华为od·华为·华为云·harmonyos·鸿蒙