高通8953平台串口配置入门

一、 串口概述

RS232、RS422、RS485都是串行数据接口标准,最初由电子工业协会(EIA)制定并发行。
RS232标准接口有25条线(4条数据,11条控制,3条定时,7条备用和未定义),常用只有9条线,RTS/CTS(请求发送/清除发送流控制)、RXD/TXD(数据收发)、DSR/DTR(数据设置就绪/数据终端就绪流控制)、DCD(数据载波检测,也称RLSD)、Ringing-RI(振铃指示)、SG(信号地)。最简单的R232串口只需要RXD/TXD/SG三个信号。点对点通信,只能连接一个设备。通信距离最大15米,全双工。
RS422标准全称是“平衡电压数字接口电路的电气特性”。允许在相同传输线上连接多个接受节点,最多可接256个节点。采用四线接口,外加一根地线,共五根线。S-422四线接口由于采用单独的发送和接收通道,因此不必控制数据方向,各装置之间任何必须的信号交换均可以按软件方式(XON/XOFF握手)或硬件方式(一对单独的双绞线)。RS-422的最大传输距离为4000英尺(约1219米),最大传输速率为10Mb/s。其平衡双绞线的长度与传输速率成反比,在 100kb/s速率以下,才可能达到最大传输距离。只有在很短的距离下才能获得最高速率传输。一般100米长的双绞线上所能获得的最大传输速率仅为 1Mb/s。全双工,点对多通信。
RS485标准采用平衡发送和差分接收方式实现通信:发送端将串行口的ttl电平信号转换成差分信号a,b两路输出,经过线缆传输之后在接收端将差分信号还原成ttl电平信号。由于传输线通常使用双绞线,又是差分传输,所以有强大的抗共模干扰的能力,总线收发器灵敏度很高,可以检测到低至200mv电压。故传输信号在千米之外都是可以恢复。rs-485最大的通信距离约为1219m,最大传输速率为10mb/s,传输速率与传输距离成反比,在10kb/s的传输速率下,才可以达到最大的通信距离,如果需传输更长的距离,需要加485中继器。rs-485采用半双工工作方式,支持多点数据通信。rs-485总线网络拓扑一般采用终端匹配的总线型结构。即采用一条总线将各个节点串接起来,不支持环形或星型网络。如果需要使用星型结构,就必须使用485中继器或者485集线器才可以。rs-485总线一般最大支持32个节点,如果使用特制的485芯片,可以达到128个或者256个节点,最大的可以支持到400个节点。两线制,半双工,点对多通信(四线制通信只支持点对点已经淘汰)

二、 平台串口介绍

以8953平台为例。
在这里插入图片描述
上图列出了平台所支持的所有spi,uart,i2c资源,共包括八组spi, 四组uart,八组i2c。这里四组串口对应BLSP2,BLSP4,BLSP5,BLSP6。
每组BLSP包括四组QUP和两组UARTcores。共支持两组低速串口和两组高速串口,高速串口最高速率4Mbps。
串口base addresses如下图:可根据此图配置devicetree文件。
在这里插入图片描述
串口所用中断号如下图:可根据此图配置devicetree文件。
在这里插入图片描述

三、 Device tree如何配置串口

需要修改文件:
 Device tree source – /arch/arm/boot/dts/qcom/msm8953.dtsi
 Clock table – /drivers/clk/msm/clock-gcc-8953.c (or clock-gcc-titanium.c)
in this file, update the msm_clocks_lookup[] table.(一般不需要修改)
 GPIO table – /kernel/arch/arm/boot/dts/qcom/msm8953-pinctrl.dtsi
低速串口:
 /arch/arm/boot/dts/qcom/msm8953.dtsi:

blsp1_uart0: serial@78af000 {
compatible = "qcom,msm-lsuart-v14";
reg = <0x78af000 0x200>;
interrupts = <0 107 0>;
status = "disabled"; //change “ok” to enable
clocks = <&clock_gcc clk_gcc_blsp1_uart1_apps_clk>,
<&clock_gcc clk_gcc_blsp1_ahb_clk>;
clock-names = "core_clk", "iface_clk";
};

这里注意clk选择与对应串口匹配的,中断号选择与对应串口匹配的,基地址选择与对应串口匹配的。
 /kernel/arch/arm/boot/dts/qcom/msm8953-pinctrl.dtsi

pmx-uartconsole {
uart_console_active: uart_console_active {
mux {
pins = "gpio4", "gpio5";
function = "blsp_uart2";
};
config {
pins = "gpio4", "gpio5";
drive-strength = <2>;
bias-disable;
};
};
uart_console_sleep: uart_console_sleep {
mux {
pins = "gpio4", "gpio5";
function = "blsp_uart2";
};
config {
pins = "gpio4", "gpio5";
drive-strength = <2>;
bias-pull-down;
};
};
};//注意在合适的地方通过default来调用pinctrl。

高速串口:
高速串口相较低速串口增加了一组中断如下图;
在这里插入图片描述
所需要修改的文件参考低速串口

blsp1_uart1: uart@78b0000 { 
compatible = "qcom,msm-hsuart-v14"; 
reg = <0x78b0000 0x200>, 和低速串口一致
<0x7884000 0x1f000>; 高速串口新增
reg-names = "core_mem", "bam_mem"; 
interrupt-names = "core_irq", "bam_irq", "wakeup_irq"; 
#address-cells = <0>; 
interrupt-parent = <&blsp1_uart1>; 需要改动
interrupts = <0 1 2>; 
#interrupt-cells = <1>;
interrupt-map-mask = <0xffffffff>;
interrupt-map = <0 &intc 0 108 0需要改动
1 &intc 0 238 0需要改动
2 &tlmm 13 0>;需要改动
qcom,inject-rx-on-wakeup;
qcom,rx-char-to-inject = <0xFD>;
qcom,master-id = <86>;
clock-names = "core_clk", "iface_clk";
clocks = <&clock_gcc clk_gcc_blsp1_uart2_apps_clk>,需要改动
<&clock_gcc clk_gcc_blsp1_ahb_clk>;需要改动
pinctrl-names = "sleep", "default";
pinctrl-0 = <& blsp1_uart1_sleep >;需要改动
pinctrl-1 = <& blsp1_uart1_active >;需要改动
qcom,bam-tx-ep-pipe-index = <2>;
qcom,bam-rx-ep-pipe-index = <3>;
qcom,msm-bus,name = "blsp1_uart1";需要改动
qcom,msm-bus,num-cases = <2>;
qcom,msm-bus,num-paths = <1>;
qcom,msm-bus,vectors-KBps =
<86 512 0 0>,
<86 512 500 800>;
};
Blsp1_uart1_active: blsp1_uart1_active {
mux {
pins = "gpio12", "gpio13", "gpio14", "gpio15";
function = "blsp_uart4";
};
config {
pins = "gpio12", "gpio13", "gpio14", "gpio15";
drive-strength = <2>;
bias-disable;
};
};
Blsp1_uart1_sleep: blsp1_uart1_sleep {
mux {
pins = "gpio12", "gpio13", "gpio14", "gpio15";
function = "gpio";
};
config {
pins = "gpio12", "gpio13", "gpio14", "gpio15";
drive-strength = <2>;
bias-disable;
};
};

四、 bootloader如何配置串口

所需要的配置文件:
/lk/project/msm8953.mk
打开 DEFINES += WITH_DEBUG_UART=1
/lk/target/msm8953/init.c(对应到具体的每个项目文件夹中)

void target_early_init(void)
{
#if WITH_DEBUG_UART
/*
First argument represents the ID (can be any since it's not used)
Second argument, if it is a GSBI base, must be 0
Third Argument is the physical address for UART CORE defined in
/bootable/bootloader/lk/platform/msm8953/include/platform/iomap.h
*/
uart_dm_init(1, 0, BLSP1_UART2_BASE);//it is uart[0..2] instead of uart[1..2]
#endif
}

/lk/platform/msm8953/acpuclock.c

void clock_config_uart_dm(uint8_t id)
{
int ret;
/*
NOTE: In clock regime clocks are # from 1 to 2 so UART0 would
be identified as UART1*/
//iface_clk is BLSP clk
ret = clk_get_set_enable("uart2_iface_clk", 0, 1);
//core_clock is UART clock.
ret = clk_get_set_enable("uart2_core_clk", 7372800, 1);
}

/lk/platform/msm8953/gpio.c

void gpio_config_uart_dm(uint8_t id)
{
/*Configure the RX/TX GPIO
Argument 1: GPIO #
Argument 2: Function (See device pinout for more information)
Argument 3: Input/Ouput (Can be 0/1)
Argument 4: Should be no PULL
Argument 5: Drive strength
Argument 6: Output Enable (Can be 0/1)*/
gpio_tlmm_config(5, 2, GPIO_INPUT, GPIO_NO_PULL,
GPIO_8MA, GPIO_DISABLE);
gpio_tlmm_config(4, 2, GPIO_OUTPUT, GPIO_NO_PULL,
GPIO_8MA, GPIO_DISABLE);
}//此串口用于lk的log输出

五、bootloader中串口相关代码

kmian(lk\kernel\main.c)
|-target_early_init(lk\target\LBxxxx\init.c)
|-uart_dm_init(lk\platform\msm_shared\uart_dm.c)
|-clock_config_uart_dm(lk\platform\msm8953\acpuclock.c)
|-gpio_config_uart_dm(lk\platform\msm8953\gpio.c)
Target_early_init函数中仅对log串口进行的初始化
平台相关的文件都在lk\platform\msm8953下面,包括iomap.h等头文件和源文件。
Lk中通过读写寄存器实现串口功能。

六、 kernel中串口驱动文件:

低速串口:msm_serial_hs_lite.c
高速串口:msm_serial_hs.c

实际应用中可能会用到重新定义串口名字的情况,这里说明一下如何重新定义串口命名。

 低速串口:[ttyHSL] [x]
Msm_uart_ports数组定义了所支持的串口数量,默认代码支持3组。Line参数对应串口名称后面的数字。根据line值去匹配串口.
[x]可通过devicestree中的别名对串口名字进行重定义:这里的修改只针对line值。
aliases{
Serial0 = &blsp1_uart0;
Serial5 = &blsp2_uart1;
}
[ttyHSL]串口名前半部分通过uart_driver中的dev_name来修改,console中的name来修改。

 高速串口:[ttyHS] [x]
与低速串口不一样的地方在于默认最高支持的串口号到256。
[x]可通过devicestree去定义,即串口的id,后面又将id赋值给line.
aliases{
Uart2 = &blsp1_uart1;
Uart4 = &blsp2_uart1;
}
[ttyHS]串口前半部分通过uart_driver中的dev_name来修改.

七、 调试中遇到的问题

卫星通信模块用串口进行通信,且采用CMUX进行多路复用,在ppp拨号时,主板死机。Log上报为:
[ 269.341861] logd: logdr: UID=2000 GID=2000 PID=4031 b tail=0 logMask=19 pid=0 start=0ns timeout=0ns
[ 271.006799] BUG: spinlock recursion on CPU#7, logcat/4031
[ 271.011174] lock: msm_hsl_uart_ports+0x2f0/0x8d0, .magic: dead4ead, .owner: logcat/4031, .owner_cpu: 7
[ 271.020537] Causing a watchdog bite!
Log初步分析为串口死锁,即串口的递归调用属于死锁的第一种AA情况。
因之前遇到过串口接收丢数据的情况,原因是存在其他服务程序,与当前服务程序所用的串口一样,导致数据被其他服务程序抢走。所以首先排除串口命名一致,放止串口的重复打开,修改名称后问题仍存在。
更换为高速串口,问题仍存在。
根据log提示,定位到最后log出现的函数,增加dump代码:
在这里插入图片描述
通过查看函数的调用关系发现死锁位置,如下图:
在这里插入图片描述
最终通过增加新锁解决此问题。

八、 串口回环测试

首先将RX与TX短接
echo 1 > /sys/kernel/debug/msm_serial_hs/loopback.0 //打开回环开关
cat /sys/kernel/debug/msm_serial_hs/loopback.0 //确保已经打开回环开关了
cat /dev/ttyHS0
echo 111 > /dev/ttyHS0
查看是否有数据被读出

九、参考文档

sp80-p3255-6_c_msm8953_sdm450_linux_android_software_porting_manual.pdf
80-pc173-5b_f_sdm450_sda450_digital_baseband_design_guidelines_training_guidelines.pdf

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值