u-boot移植随笔(3):u-boot shell与ASCII码

u-boot移植随笔:u-boot shell与ASCII码 前几天让u-boot的shell更接近“shell”,发现可以使用Ctrl-p等等来控制,心里总在想它们是怎么实现的,怎么能读取到我按下Ctrl-p的呢?今天又看了u-boot的代码,找了好久,蓦然回首,原来是在./common下面的main.c中,——我就说呢,在SI中看这个文件时候,没发现旁边下拉条那么短,聪明人一看就知道这里面有不少东西!唉,一时没注意。

看一下main.c文件中的cread_line函数(这个函数有一个while(1)死循环,遇到回车、Ctrl-c才跳出,命令补齐也在这个函数中体现),由

1
ichar = getcmd_getch();

获取到输入的字符,经过很复杂的处理后,终于等到回车键按下了(不按下怎么执行命令呢?对吧?),使用cread_add_to_hist保存起来——为了实现命令历史,又牵出另外的很复杂的过程。解析输入的字符就完成了,至于之后的处理,依然是很复杂的很复杂的过程。
找啊找啊,终于发现这么几行:

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
case CTL_CH('a'):
BEGINNING_OF_LINE();
break;
case CTL_CH('c'): /* ^C - break */
*buf = '/0'; /* discard input */
return (-1);
case CTL_CH('f'):
if (num < eol_num) {
getcmd_putch(buf[num]);
num++;
}
break;
case CTL_CH('b'):
if (num) {
getcmd_putch(CTL_BACKSPACE);
num--;
}
break;
case CTL_CH('d'):
if (num < eol_num) {
wlen = eol_num - num - 1;
if (wlen) {
memmove(&buf[num], &buf[num+1], wlen);
putnstr(buf + num, wlen);
}

getcmd_putch(' ');
do {
getcmd_putch(CTL_BACKSPACE);
} while (wlen--);
eol_num--;
}
break;

CTL_CH()是一个宏,从字面上理解是Ctrl加上一个字符,定义如下:

1
#define CTL_CH(c)  ((c) - 'a' + 1)

我很奇怪,怎么减去个’a’再加个1就能判断我按下Ctrl了呢?我打开VC建好工程,测试一下CTL_CH(‘b’),结果给我个笑脸,更百思不得其解。
又想到去查ASCII码表,开始找那几个基本上几乎一样,没有什么有用的信息。后来不小心看到一张内容稍微多一点,上面有一栏是“终端显示”,我一看,前面怎么排列得这么整齐?^A到^Z,难道这个就是Ctrl-A到Ctrl-Z?我猜应该是了,不然找不到其它理由了。你看,^B是2,’b’-‘a’+1就等于2啊!肯定是这个原因!
但是ASCII码前面三十几个具体是干嘛的?网上都说是控制、通信用,但没亲自捣鼓,除了“\t”、“\n”经常用外,其它的没印象啊。如果要追到底,估计要追究到那个久远的年代了,算了,等哪天闲得没事干了再去追吧。
以前只知道emacs能使用ctrl-p、ctrl-n,现在,u-boot的shell、linux的shell中都能使用ctrl-p、ctrl-n等等,它们的原理应该是一样的。
本文假设已经实现了u-boot shell自动补齐、命令历史等功能(就是加多两个宏),并且没有深入追究那些代码来龙去脉。
本文即兴而写,随意看看,不必当真。

下面附上一份经过山人结合网上许多资料整理出的ASCII码表格,表格整理得不美观,但应该不会影响阅读。

                        ASCII码表         

 

Dec

Hex

Oct

Char

Terminal

    备注

Dec

Hex

Oct

Char

0

0

0

(null)

^@

64

40

100

@

1

1

1

soh

^A

文件头的开始

65

41

101

A

2

2

2

stx

^B

文本的开始

66

42

102

B

3

3

3

etx

^C

文本的结束

67

43

103

C

4

4

4

eot

^D

传输的结束

68

44

104

D

5

5

5

enq

^E

询问

69

45

105

E

6

6

6

ack

^F

确认

70

46

106

F

7

7

7

bel

^G

响铃

71

47

107

G

8

8

10

bs

^H

后退

72

48

110

H

9

9

11

ht

^I

水平跳格

73

49

111

I

10

0A

12

nl

^J

换行

74

4A

112

J

11

0B

13

vt

^K

垂直跳格

75

4B

113

K

12

0C

14

ff

^L

格式馈给

76

4C

114

L

13

0D

15

er

^M

回车

77

4D

115

M

14

0E

16

so

^N

向外移出

78

4E

116

N

15

0F

17

si

^O

向内移入

79

4F

117

O

16

10

20

dle

^P

数据传送换码

80

50

120

P

17

11

21

dc1

^Q

设备控制1

81

51

121

Q

18

12

22

dc2

^R

设备控制2

82

52

122

R

19

13

23

dc3

^S

设备控制3

83

53

123

S

20

14

24

dc4

^T

设备控制4

84

54

124

T

21

15

25

nak

^U

否定

85

55

125

U

22

16

26

syn

^V

同步空闲

86

56

126

V

23

17

27

etb

^W

传输块结束

87

57

127

W

24

18

30

can

^X

取消

88

58

130

X

25

19

31

em

^Y

媒体结束

89

59

131

Y

26

1A

32

sub

^Z

90

5A

132

Z

27

1B

33

esc

^[

退出

91

5B

133

[

28

1C

34

fs

^*

域分隔符

92

5C

134

/

29

1D

35

gs

^]

组分隔符

93

5D

135

]

30

1E

36

re

^^

记录分隔符

94

5E

136

^

31

1F

37

us

^_

单元分隔符

95

5F

137

_

32

20

40

sp

(Space)

空格

96

60

140

'

33

21

41

!

 

 

97

61

141

a

34

22

42

"

 

 

98

62

142

b

35

23

43

#

 

 

99

63

143

c

36

24

44

$

 

 

100

64

144

d

37

25

45

%

 

 

101

65

145

e

38

26

46

&

 

 

102

66

146

f

39

27

47

`

 

 

103

67

147

g

40

28

50

(

 

 

104

68

150

h

41

29

51

)

 

 

105

69

151

i

42

2A

52

*

 

 

106

6A

152

j

43

2B

53

+

 

 

107

6B

153

k

44

2C

54

,

 

 

108

6C

154

l

45

2D

55

-

 

 

109

6D

155

m

46

2E

56

.

 

 

110

6E

156

n

47

2F

57

/

 

 

111

6F

157

o

48

30

60

0

 

 

112

70

160

p

49

31

61

1

 

 

113

71

161

q

50

32

62

2

 

 

114

72

162

r

51

33

63

3

 

 

115

73

163

s

52

34

64

4

 

 

116

74

164

t

53

35

65

5

 

 

117

75

165

u

54

36

66

6

 

 

118

76

166

v

55

37

67

7

 

 

119

77

167

w

56

38

70

8

 

 

120

78

170

x

57

39

71

9

 

 

121

79

171

y

58

3A

72

:

 

 

122

7A

172

z

59

3B

73

;

 

 

123

7B

173

{

60

3C

74

 

 

124

7C

174

|

61

3D

75

=

 

 

125

7D

175

}

62

3E

76

 

 

126

7E

176

~

63

3F

77

?

 

 

127

7F

177

del

1、本表列出了ASCII字符集。每一个字符有它的十进制值,十六进制值,终端上的显示结果,ASCII助记名,和ASCII控制字符定义。
2、ASCII字符60—7Fh不能被存储到内存单元或数据记录文件。这些值被转变到40h - 5Fh范围内的等价大写形式。这些字符可以被存到缓冲区,并且在通讯时被发送和接收。
3、ASCII表0-1F及7F共33个字符是控制字符或通信专用字符,其余均为可显示字符。

PS:另外一份表:

Bin Dec Hex 缩写/字符 解释
00000000 0 00 NUL(null) 空字符
00000001 1 01 SOH(start of headling) 标题开始
00000010 2 02 STX (start of text) 正文开始
00000011 3 03 ETX (end of text) 正文结束
00000100 4 04 EOT (end of transmission) 传输结束
00000101 5 05 ENQ (enquiry) 请求
00000110 6 06 ACK (acknowledge) 收到通知
00000111 7 07 BEL (bell) 响铃
00001000 8 08 BS (backspace) 退格
00001001 9 09 HT (horizontal tab) 水平制表符
00001010 10 0A LF (NL line feed, new line) 换行键
00001011 11 0B VT (vertical tab) 垂直制表符
00001100 12 0C FF (NP form feed, new page) 换页键
00001101 13 0D CR (carriage return) 回车键
00001110 14 0E SO (shift out) 不用切换
00001111 15 0F SI (shift in) 启用切换
00010000 16 10 DLE (data link escape) 数据链路转义
00010001 17 11 DC1 (device control 1) 设备控制1
00010010 18 12 DC2 (device control 2) 设备控制2
00010011 19 13 DC3 (device control 3) 设备控制3
00010100 20 14 DC4 (device control 4) 设备控制4
00010101 21 15 NAK (negative acknowledge) 拒绝接收
00010110 22 16 SYN (synchronous idle) 同步空闲
00010111 23 17 ETB (end of trans. block) 传输块结束
00011000 24 18 CAN (cancel) 取消
00011001 25 19 EM (end of medium) 介质中断
00011010 26 1A SUB (substitute) 替补
00011011 27 1B ESC (escape) 溢出
00011100 28 1C FS (file separator) 文件分割符
00011101 29 1D GS (group separator) 分组符
00011110 30 1E RS (record separator) 记录分离符
00011111 31 1F US (unit separator) 单元分隔符
00100000 32 20 (space) 空格
00100001 33 21 !
00100010 34 22 "
00100011 35 23 #
00100100 36 24 $
00100101 37 25 %
00100110 38 26 &
00100111 39 27 '
00101000 40 28 (
00101001 41 29 )
00101010 42 2A *
00101011 43 2B +
00101100 44 2C ,
00101101 45 2D -
00101110 46 2E .
00101111 47 2F /
00110000 48 30 0
00110001 49 31 1
00110010 50 32 2
00110011 51 33 3
00110100 52 34 4
00110101 53 35 5
00110110 54 36 6
00110111 55 37 7
00111000 56 38 8
00111001 57 39 9
00111010 58 3A :
00111011 59 3B ;
00111100 60 3C <
00111101 61 3D =
00111110 62 3E >
00111111 63 3F ?
01000000 64 40 @
01000001 65 41 A
01000010 66 42 B
01000011 67 43 C
01000100 68 44 D
01000101 69 45 E
01000110 70 46 F
01000111 71 47 G
01001000 72 48 H
01001001 73 49 I
01001010 74 4A J
01001011 75 4B K
01001100 76 4C L
01001101 77 4D M
01001110 78 4E N
01001111 79 4F O
01010000 80 50 P
01010001 81 51 Q
01010010 82 52 R
01010011 83 53 S
01010100 84 54 T
01010101 85 55 U
01010110 86 56 V
01010111 87 57 W
01011000 88 58 X
01011001 89 59 Y
01011010 90 5A Z
01011011 91 5B [
01011100 92 5C \
01011101 93 5D ]
01011110 94 5E ^
01011111 95 5F _
01100000 96 60 `
01100001 97 61 a
01100010 98 62 b
01100011 99 63 c
01100100 100 64 d
01100101 101 65 e
01100110 102 66 f
01100111 103 67 g
01101000 104 68 h
01101001 105 69 i
01101010 106 6A j
01101011 107 6B k
01101100 108 6C l
01101101 109 6D m
01101110 110 6E n
01101111 111 6F o
01110000 112 70 p
01110001 113 71 q
01110010 114 72 r
01110011 115 73 s
01110100 116 74 t
01110101 117 75 u
01110110 118 76 v
01110111 119 77 w
01111000 120 78 x
01111001 121 79 y
01111010 122 7A z
01111011 123 7B {
01111100 124 7C |
01111101 125 7D }
01111110 126 7E ~
01111111 127 7F DEL (delete) 删除