本文主要介绍了在PicoLIN硬件平台配合LIN压力测试实现的一些配置方法

1. Break长度设置

基于PicoLIN这个简单的平台,是无法实现任意设置Break长度的。当然,在实际的测试过程中,既然是压力测试,只需要重点设置几个长度,重点是最小Break长度和最大Break长度。

T break MIN T break MAX
13 Tbit 26.6 Tbit

PicoLIN充当Master如果改变只改变Break长度,可以通过改变波特率间接实现。在STM32芯片中,LIN主机发送Break为标准的13Tbit,在发送Break前将波特率改小,可以间接增加Break的长度,发送完Break之后,再将波特率切换回来即可。

针对测试我们预设11、13、20、26、28五种情况,基于19200波特率,1Tbit为52.08us,实际设置数值是通过标定而来,而非简单的计算,STM32本身的波特率也有比较大误差

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**  
* @brief setting next request header's break length * * @param length
* @return uint8_t
*/
uint8_t LinDriver::setBreakLength(uint8_t length) {
breakTbitLength = length;
/* only support 11、13、20、26、28 */
switch (breakTbitLength) {
case 11u: {
setBaudrate(23800u);
} break;
case 13u: {
setBaudrate(19200u);
} break;
case 20u: {
/* 19200 * 13 / 20 = 12480 */
setBaudrate(11800);
} break;
case 26u: {
/* 19200 * 13 / 26 = 9600 */
setBaudrate(8700);
} break;
case 28u: {
/* 19200 * 13 / 28 = 8914 */
setBaudrate(7680u);
} break;
default: {
breakTbitLength = 13u;
setBaudrate(19200u);
} break;
}
return 0;
}

Break 11 Tbit 长度实测

基准波特率19200bps,1位时间52.08微妙:

T11=T1×11=52.08×11=572.88usT_{11}=T_{1} \times 11 = 52.08 \times 11 = 572.88 us

Break 20 Tbit 长度实测

T20=T1×20=52.08×20=1041.6usT_{20}=T_{1} \times 20 = 52.08 \times 20 = 1041.6 us

Break 26 Tbit 长度实测

T26=T1×26=52.08×26=1354.08usT_{26}=T_{1} \times 26 = 52.08 \times 26 = 1354.08 us

2. Break Delimiter长度设置

基于PicoLIN这个简单的平台,想改变Delimiter的长度有两种做法:

  • 一、发送完Break之后,强制延迟,再发送0x55同步段
  • 二、使用发送特定波特率下的数据代替发送Break

这里我们选择第二种方法,因为在Break之后的延时很难控制,我们改变波特率之后通过发送0xe0、0xf0、0xf8来模拟发送Break和Delimiter段

T Delimiter MIN T Delimiter MAX
1 Tbit 14.6 Tbit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
* @brief setting next request header's break delimiter length
*
* @param deli
* @return uint8_t
*/
uint8_t LinDriver::setDelimiter(uint8_t deli) {
breakDelimiterTbitLength = deli;
/* only support 1、10、14、21 */
switch (breakDelimiterTbitLength) {
case 1u: {
setBaudrate(19200u);
} break;
case 10u: {
/* 0x11100000 as 13.4 Tbit break and 10 Tbit deli*/
setBaudrate(8620u);
} break;
case 14u: {
/* 0x11110000 as 13 Tbit break and 14.5 Tbit deli*/
setBaudrate(7200u);
} break;
case 21u: {
/* 0x11111000 as 13 Tbit break and 21 Tbit deli*/
setBaudrate(5800u);
} break;
default: {
breakDelimiterTbitLength = 1u;
setBaudrate(19200u);
} break;
}
return 0;
}

发送报头的实现如下(非完整代码):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
 * @brief methord send header
 *
 * @param id
 * @param rLen
 * @return uint8_t
 */
uint8_t LinDriver::sendHeader(uint8_t id, uint8_t rLen) {
...
if(breakDelimiterTbitLength != 1u) {
if (breakDelimiterTbitLength == 10u) {
writeByte(0xe0);
} else if (breakDelimiterTbitLength == 14u) {
writeByte(0xf0);
} else if (breakDelimiterTbitLength == 21u) {
writeByte(0xf8);
} else if (breakDelimiterTbitLength == 2u) {
writeByte(0x00);
} else if (breakDelimiterTbitLength == 3u) {
writeByte(0x00);
} else if (breakDelimiterTbitLength == 4u) {
sendBreak();
}
} else {
sendBreak();
}
writeByte(0x55);
...
}

Delimiter 10 Tbit 长度实测

T10=T1×10=52.08×10=520.8usT_{10}=T_{1} \times 10 = 52.08 \times 10 = 520.8 us

Delimiter 14 Tbit 长度实测

T14=T1×14=52.08×14=729.12usT_{14}=T_{1} \times 14 = 52.08 \times 14 = 729.12 us

Delimiter 21 Tbit 长度实测

T21=T1×21=52.08×21=1093.68usT_{21}=T_{1} \times 21 = 52.08 \times 21 = 1093.68 us

3. Header长度设置

基于PicoLIN简易平台,同时改变Break和Delimiter的长度的实现方式与只改变Break Delimite的思路一致,程序处理上可以做区分,发送的数据是不一样的

T Header MIN T Header MAX
34 Tbit 47.6 Tbit

可设置测试用例表如下

No. Break Length Delimiter Length InterByte Length Header Length Baudrate
1 13 Tbit 1 Tbit 0 Tbit 34 Tbit 19296 (+0.5%)
2 18 Tbit 2 Tbit 6.6 Tbit 46.6 Tbit 19104 (-0.5%)
3 15 Tbit 3 Tbit 2 Tbit 40 Tbit 19104 (-0.5%)
4 13 Tbit 1 Tbit 12.6 Tbit 46.6 Tbit 19104 (-0.5%)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
* @brief setting next request header's length
*
* @param index
* @return uint8_t
*/
uint8_t LinDriver::setHeaderLength(uint8_t index) {
switch (index) {
case 1u: {
breakDelimiterTbitLength = 1u;
setBaudrate(19104u);
} break;
case 2u: {
breakDelimiterTbitLength = 2u;
setBaudrate(9800);
} break;
case 3u: {
breakDelimiterTbitLength = 3u;
setBaudrate(11500);
} break;
case 4u: {
breakDelimiterTbitLength = 4u;
setBaudrate(19104u);
} break;
default: {
breakDelimiterTbitLength = 1u;
} break;
}
return 0;
}

发送报头的实现如下(非完整代码):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
 * @brief methord send header
 *
 * @param id
 * @param rLen
 * @return uint8_t
 */
uint8_t LinDriver::sendHeader(uint8_t id, uint8_t rLen) {
...
if(breakDelimiterTbitLength != 1u) {
if (breakDelimiterTbitLength == 10u) {
writeByte(0xe0);
} else if (breakDelimiterTbitLength == 14u) {
writeByte(0xf0);
} else if (breakDelimiterTbitLength == 21u) {
writeByte(0xf8);
} else if (breakDelimiterTbitLength == 2u) {
writeByte(0x00);
} else if (breakDelimiterTbitLength == 3u) {
writeByte(0x00);
} else if (breakDelimiterTbitLength == 4u) {
sendBreak();
}
} else {
sendBreak();
}
writeByte(0x55);
...
}

Header2 报头长度实测

Break长度18,Delimiter长度2,InterByte长度6.6,总长度46.6

T46.6=T1×46.6=52.345×46.6=2439.27usT_{46.6}=T_{1} \times 46.6 = 52.345 \times 46.6 = 2439.27 us

Header3 报文长度实测

Break长度15,Delimiter长度3,InterByte长度2,总长度40

T40=T1×40=52.345×40=2093.8usT_{40}=T_{1} \times 40 = 52.345 \times 40 = 2093.8 us

Header4 报文长度实测

Break长度13,Delimiter长度1,InterByte长度12.6,总长度46.6