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.1.2 APP控制台打印
其架构为:
- 我们编写的应用程序,调用printf时,那些信息从哪里打印出来?——控制台 console,但是它可能代表不同的设备。
- 在串口上运行程序,控制台——**串口 serial **。
- 远程登录板子后运行程序,控制台——远程登录终端 telnet。
控制台的实现分为4层:
1.1.2.1 建立联系
-
对于console <–> serial,其建立联系使用
INT32 system_console_init(const CHAR *deviceName)
函数- 先分辨出:使用具体何种device(serial / telnet)
- 后建立联系
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
-
对于serial <–> uart,其建立联系使用
INT32 virtual_serial_init(const CHAR *deviceName)
函数从名字上看,
/dev/serial
被称为virtual serial,虚拟串口。它只是起一个中转的作用,无论是APP还是内核,使用/dev/serial
时,都是再次跳转去执行具体串口设备驱动程序的函数
1.1.2.2 uart与具体的dev
这是真正操作硬件的驱动程序,它分为两部分:device_t
、driver_t
。
- 在
device_t
中设置资源,比如寄存器物理基地址、中断号等 - 在
driver_t
中提供函数,比如device_probe
、device_attach
函数- 当内核发现有名字系统的
device_t
、driver_t
时 - 就会调用
driver_t
中的device_probe
、device_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);