当前位置:   article > 正文

鸿蒙移植随笔

鸿蒙移植随笔

STM32MP157—鸿蒙Liteos_a移植随笔

  • 硬件平台:韦东山嵌入式Linxu开发板(STM32MP157)
  • 软件平台:运行于VMware Workstation Pro 下 UbuntuLTS18.04_x64 系统


第一章 串口移植

1.1 Liteos_a串口架构分析

1.1.1 内核打印函数实现

内核打印函数为PRINT_RELEASE(fmt, args...),宏定义于openharmony\kernel\liteos_a\kernel\include\los_printf.h

#define PRINT_DEBUG(fmt, args...)    LOS_LkPrint(LOS_DEBUG_LEVEL, __FUNCTION__, __LINE__, fmt, ##args)
#define PRINT_INFO(fmt, args...)     LOS_LkPrint(LOS_INFO_LEVEL, __FUNCTION__, __LINE__, fmt, ##args)
#define PRINT_WARN(fmt, args...)     LOS_LkPrint(LOS_WARN_LEVEL, __FUNCTION__, __LINE__, fmt, ##args)
#define PRINT_ERR(fmt, args...)      LOS_LkPrint(LOS_ERR_LEVEL, __FUNCTION__, __LINE__, fmt, ##args)
#define PRINTK(fmt, args...)         LOS_LkPrint(LOS_COMMON_LEVEL, __FUNCTION__, __LINE__, fmt, ##args)
#define PRINT_EMG(fmt, args...)      LOS_LkPrint(LOS_EMG_LEVEL, __FUNCTION__, __LINE__, fmt, ##args)
#define PRINT_RELEASE(fmt, args...)  LOS_LkPrint(LOS_COMMON_LEVEL, __FUNCTION__, __LINE__, fmt, ##args)
#define PRINT_TRACE(fmt, args...)    LOS_LkPrint(LOS_TRACE_LEVEL, __FUNCTION__, __LINE__, fmt, ##args)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

其调用关系为:可以看到其最终实现的是输出单个字符

PRINT_EMG(fmt, args...)
LOS_LkPrint(LOS_EMG_LEVEL, __FUNCTION__, __LINE__, fmt, ##args)
LK_FUNC g_osLkHook
VOID OsLkDefaultFunc(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, va_list ap);
VOID LkDprintf(const CHAR *fmt, va_list ap)
VOID OsVprintf(const CHAR *fmt, va_list ap, OutputType type)
VOID UartPuts(const CHAR *s, UINT32 len, BOOL isLock)
UINT32 UartPutsReg(UINTPTR base, const CHAR *s, UINT32 len, BOOL isLock)
STATIC VOID UartPutStr(UINTPTR base, const CHAR *s, UINT32 len)
STATIC VOID UartPutcReg(UINTPTR base, CHAR c)

在这里插入图片描述

1.1.2 APP控制台打印

其架构为:

  • 我们编写的应用程序,调用printf时,那些信息从哪里打印出来?——控制台 console,但是它可能代表不同的设备。
  • 串口上运行程序,控制台——**串口 serial **。
  • 远程登录板子后运行程序,控制台——远程登录终端 telnet

控制台的实现分为4层

/dev/console1
/dev/serial
/dev/telnet
/dev/uartdev-0
/dev/uartdev-1
uart_ops
1.1.2.1 建立联系
  • 对于console <–> serial,其建立联系使用INT32 system_console_init(const CHAR *deviceName)函数

    1. 分辨出:使用具体何种device(serial / telnet)
    2. 建立联系

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传在这里插入图片描述

  • 对于serial <–> uart,其建立联系使用INT32 virtual_serial_init(const CHAR *deviceName)函数

    从名字上看,/dev/serial被称为virtual serial,虚拟串口。它只是起一个中转的作用,无论是APP还是内核,使用/dev/serial,都是再次跳转去执行具体串口设备驱动程序的函数

在这里插入图片描述

1.1.2.2 uart与具体的dev

这是真正操作硬件的驱动程序,它分为两部分:device_tdriver_t

  • device_t中设置资源,比如寄存器物理基地址、中断号等
  • driver_t中提供函数,比如device_probedevice_attach函数
    • 当内核发现有名字系统的device_tdriver_t
    • 就会调用driver_t中的device_probedevice_attach函数
    • 在里面根据device_t得到资源、注册驱动register_driver

这种写驱动程序的方法,被称为分离:操作函数、资源分离。
以后想换一个硬件,只需要修改device_t就可以,driver_t保存不变。

  • device_t
    在这里插入图片描述

  • driver_t
    在这里插入图片描述

  • uartdev_t

    /dev/uartdev-0对应的驱动程序时uartdev_fops,它通过uart_ops来操作硬件。
    在这里插入图片描述

  • uart_ops

    在UART驱动程序里,我们只需要提供硬件操作部分:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传在这里插入图片描述

    uart_ops里有4个函数:

    • config:配置串口,比如波特率等
    • startup:启动串口,比如注册中断处理函数、启动串口
    • start_tx:发送字符串
    • shutdown:关闭串口

    串口就两大功能:发送数据、接收数据
    在Liteos-a中,发送数据比较简单:没有使用中断,而是使用查询方式逐个发送核心是UartPutcReg
    接收数据时使用中断,所以需要注册串口接收中断处理函数,它要做的事情是:

    • 发生中断时,读取硬件获得字符,可能有多个字符
    • 处理特殊字符:比如不`\r`换为`\n`
    • 通知上层代码:udd->recv(udd, buf, count);

1.2 uart串口架构

在这里插入图片描述

第二章 GenericTimer架构分析

在这里插入图片描述

第三章 存储设备

在这里插入图片描述

第四章 根文件系统的生成过程

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/274790
推荐阅读
相关标签
  

闽ICP备14008679号