鸿蒙移植i.mx6ull(九) 串口移植(基于IMX6ULL)

Ps:这个鸿蒙系列是韦东山老师录制的视频和开发手册为基础,请大家支持韦老师。 这个专栏是:
1.学习的笔记记录。
2.整理和知识点汇总。
3.个人做的项目经验汇总。

1. Liteos-a中串口的使用

1.1 内核里打印

内核打印函数是PRINT_RELEASE,它的内部调用关系如下:

PRINT_RELEASE
    LOS_LkPrint
    	g_osLkHook
    		OsLkDefaultFunc
    			OsVprintf
    				UartPuts
    					UartPutsReg
    						UartPutStr
    							UartPutcReg

我们要实现UartPutcReg,用来输出单个字符。

1.2 APP控制台

我们编写的应用程序,调用printf时,那些信息从哪里打印出来?从控制台。 在串口上运行程序,控制台就是串口。
远程登录板子后运行程序,控制台就是远程登录终端。

控制台的实现分为4层:

/dev/console1
/dev/serial
/dev/telnet
/dev/uartdev-0
/dev/uartdev-1
uart_ops

1.2.1 /dev/console

init进程打开的就是/dev/console,它会打开shell
我们在shell里执行各种APP时,这些APP会继承父进程的3个设备:标准输入、标准输出、标准错误,都对应/dev/console
我们编写的APP,一般不需要自己去打开/dev/console,它已经继承得到了。
在串口上运行程序,/dev/console就是串口。 远程登录板子后运行程序,/dev/console就是远程登录终端。
所以/dev/console表示的是当前终端,它可能对应不同的设备,比如/dev/serial/dev/telnet

1.2.2 /dev/serial

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

在这里插入图片描述

那么,/dev/serial这个虚拟串口,怎么跟具体串口挂钩?也就是上图中,GetFileOps函数为何能得到具体串口的驱动程序?
方法如下图所示:

在这里插入图片描述

virtual_serial_init函数会找到/dev/uartdev-0的驱动程序(即它对应的struct inode,里面含有file_operations_vfs)。

1.2.3 /dev/uartddev-0

1. 总体介绍

这是真正操作硬件的驱动程序,它分为两部分: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保存不变。

2. device_t

示例代码:

在这里插入图片描述

3. drvier_t

先注册一个drvier_t结构体,它里面带有各类device_method_t

在这里插入图片描述

当内核发现有同名的device_tdriver_t时,就会调用driver_t里面提供的device_probedevice_attach函数。

4. uartdev_fops

device_attach函数里从device_t里获取硬件资源、注册驱动:

在这里插入图片描述

/dev/uartdev-0对应的驱动程序时uartdev_fops,它通过uart_ops来操作硬件。

1.2.4 uart_ops

UART驱动程序里,我们只需要提供硬件操作部分:

在这里插入图片描述

uart_ops里有4个函数:

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

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

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

2. 串口移植

我们的目标是:让最小系统启动。 那么对于串口,不需要考虑得很全面:

  • 不需要初始化串口:u-boot已经初始化串口了
  • 不需要动态配置串口:固定使用某个波特率等配置就可以(在u-boot里设置过了)

移植工作只需要实现这几点:

  • 串口发送单个字符

  • 注册串口接收中断函数:确定中断号、使能中断、在中断函数中读取数据

2.1 最终结果

本章节做的修改会制作为补丁文件:

  • 03_openharmony_uart_imx6ull.patch

假设目录openharmony中是未修改的代码,从没打过补丁;
假设补丁文件放在openharmony的同级目录; 打补丁方法如下:

$ cd openharmony
$ patch -p1 < ../openharmony_100ask_v1.2.patch
$ patch -p1 < ../01_openharmony_add_demo_board.patch
$ patch -p1 < ../02_openharmony_memmap_imx6ull.patch 
$ patch -p1 < ../03_openharmony_uart_imx6ull.patch

打上补丁后,可以如此编译:

$ cd kernel/liteos_a
$ cp tools/build/config/debug/demochip_clang.config .config
$ make clean
$ make

2.2 串口发送单个字符

2.3 在device_t中指定资源

需要确定2个资源:寄存器地址、中断号

2.4 实现uart_ops

UART驱动程序里,uart_ops结构体封装了UART的硬件操作:

在这里插入图片描述

uart_ops里有4个函数:

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

我们只需要实现startupstart_tx,其他函数可以设为空:

  • startup:确定中断号、request_irq、使能中断、提供中断处理函数
  • start_tx:发送字符串

2.5 GIC

kernel\liteos_a\platform\main.c中,调用OsSystemInfo打印系统信息时,代码如下:

    PRINT_RELEASE("\n******************Welcome******************\n\n"
            "Processor   : %s"
#if (LOSCFG_KERNEL_SMP == YES)
            " * %d\n"
            "Run Mode    : SMP\n"
#else
            "\n"
            "Run Mode    : UP\n"
#endif
            "GIC Rev     : %s\n"
            "build time  : %s %s\n"
            "Kernel      : %s %d.%d.%d.%d/%s\n"
            "\n*******************************************\n",
            LOS_CpuInfo(),
#if (LOSCFG_KERNEL_SMP == YES)
            LOSCFG_KERNEL_SMP_CORE_NUM,
#endif
            HalIrqVersion(), __DATE__, __TIME__,\
            KERNEL_NAME, KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE, buildType);

里面的HalIrqVersion函数用到的GIC的虚拟地址,要正确设置,否则没有打印信息。
IMX6ULL的内存映射代码里,设备空间从GIC开始映射,所以GIC的虚拟地址就是PERIPH_DEVICE_BASE

// kernel/liteos_a/kernel/base/include/los_vm_zone.h
#define GIC_VIRT_BASE    PERIPH_DEVICE_BASE

// vendor/democom/demochip/board/include/asm/platform.h
#define GIC_BASE_ADDR             (GIC_VIRT_BASE)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
将Ubuntu基于20.04版本移植到i.MX6ULL平台需要进行一系列步骤。首先,我们需要确保我们拥有i.MX6ULL开发板并正确连接上电源和显示器。然后,我们可以按照以下步骤进行移植: 1. 下载Ubuntu 20.04的ISO镜像文件,并将其烧录到一个可启动的USB设备中。 2. 在i.MX6ULL开发板上启动系统,并确保系统设置为从USB设备引导。 3. 进入系统安装界面,并按照提示进行基本设置,例如选择语言和键盘布局。 4. 在安装类型中,选择"其他选项"并进入分区工具。 5. 在分区工具中,创建一个适当的分区方案,包括根目录、/boot和swap等。 6. 选择要安装Ubuntu的目标分区,并进行扩展设置,如挂载点和格式化。确保选择的目标分区与i.MX6ULL平台兼容。 7. 点击继续安装并等待系统安装完成。 8. 完成安装后,重新启动系统并进入Ubuntu 20.04的登录界面。 9. 使用合适的凭据登录系统。 10. 安装所需的软件和驱动程序。在i.MX6ULL平台上,我们可能需要安装特定的驱动程序以确保设备正常工作。 11. 完成安装和配置后,我们现在可以开始使用Ubuntu 20.04在i.MX6ULL平台上开发和运行应用程序了。 总结来说,将Ubuntu基于20.04版本移植到i.MX6ULL平台需要确保正确安装系统镜像并进行适当的设置和配置。随后,我们可以根据需求安装软件和驱动程序,以满足在i.MX6ULL平台上的开发需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值