其实不需要用串口测试,我们可以写个小程序测试一下:
点击(此处)折叠或打开
- #include <stdio.h>
- #include <curses.h>
-
int main(int argc, char **argv)
-
{
- char a;
- char b[80];
- int i;
- printf("Please input a string
- :\n");
-
// a = getc(stdin);
- scanf("%s",b);
-
// printf("The input a string is : 0x%x\n", a);
- printf("The input char is:\n");
- for(i = 0; b[i] !='\0' && i < 80; i++ )
- printf("0x%x ",b[i]);
- printf("\n");
- return 0;
- }
测试:
点击(此处)折叠或打开
- richard@richard-H81M-DS2:~/work/driver/test$ ./test
- Please input a string:
- ^[[A^[[B^[[D^[[C
- The input char is:
- 0x1b 0x5b 0x41 0x1b 0x5b 0x42 0x1b 0x5b 0x44 0x1b 0x5b 0x43
或者执行cat -v,然后输入 ↑↓←→(其他键也可以F1~F12)。
参考知乎一位大侠的说法:
http://www.zhihu.com/question/21518507
这下就明白了。再联系 cread_line 的代码片段:
点击(此处)折叠或打开
- static int cread_line(const char *const prompt, char *buf, unsigned int *len,
- int timeout)
- {
- unsigned long num = 0;
- unsigned long eol_num = 0;
- unsigned long wlen;
- char ichar;
- int insert = 1;
- int esc_len = 0;
- char esc_save[8];
- int init_len = strlen(buf);
- int first = 1;
- if (init_len)
- cread_add_str(buf, init_len, 1, &num, &eol_num, buf, *len);
- while (1) {
- #ifdef CONFIG_BOOT_RETRY_TIME
- while (!tstc()) { /* while no incoming data */
- if (retry_time >= 0 && get_ticks() > endtime)
- return (-2); /* timed out */
- WATCHDOG_RESET();
- }
- #endif
- if (first && timeout) {
- uint64_t etime = endtick(timeout);
- while (!tstc()) { /* while no incoming data */
- if (get_ticks() >= etime)
- return -2; /* timed out */
- WATCHDOG_RESET();
- }
- first = 0;
- }
- ichar = getcmd_getch();
- if ((ichar == '\n') || (ichar == '\r')) {
- putc('\n');
- break;
- }
- /*
- * handle standard linux xterm esc sequences for arrow key, etc.
- */
- if (esc_len != 0) {
- if (esc_len == 1) {
- if (ichar == '[') {
- esc_save[esc_len] = ichar;
- esc_len = 2;
- } else {
- cread_add_str(esc_save, esc_len, insert,
- &num, &eol_num, buf, *len);
- esc_len = 0;
- }
- continue;
- }
- switch (ichar) {
- case 'D': /* <- key */
- ichar = CTL_CH('b');
- esc_len = 0;
- break;
- case 'C': /* -> key */
- ichar = CTL_CH('f');
- esc_len = 0;
- break; /* pass off to ^F handler */
- case 'H': /* Home key */
- ichar = CTL_CH('a');
- esc_len = 0;
- break; /* pass off to ^A handler */
- case 'A': /* up arrow */
- ichar = CTL_CH('p');
- esc_len = 0;
- break; /* pass off to ^P handler */
- case 'B': /* down arrow */
- ichar = CTL_CH('n');
- esc_len = 0;
- break; /* pass off to ^N handler */
- default:
- esc_save[esc_len++] = ichar;
- cread_add_str(esc_save, esc_len, insert,
- &num, &eol_num, buf, *len);
- esc_len = 0;
- continue;
- }
- }
- switch (ichar) {
- case 0x1b:
- if (esc_len == 0) {
- esc_save[esc_len] = ichar;
- esc_len = 1;
- } else {
- puts("impossible condition #876\n");
- esc_len = 0;
- }
- break;
- 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;
- case CTL_CH('k'):
- ERASE_TO_EOL();
- break;
- case CTL_CH('e'):
- REFRESH_TO_EOL();
- break;
- case CTL_CH('o'):
- insert = !insert;
- break;
- case CTL_CH('x'):
- case CTL_CH('u'):
- BEGINNING_OF_LINE();
- ERASE_TO_EOL();
- break;
- case DEL:
- case DEL7:
- case 8:
- if (num) {
- wlen = eol_num - num;
- num--;
- memmove(&buf[num], &buf[num+1], wlen);
- getcmd_putch(CTL_BACKSPACE);
- putnstr(buf + num, wlen);
- getcmd_putch(' ');
- do {
- getcmd_putch(CTL_BACKSPACE);
- } while (wlen--);
- eol_num--;
- }
- break;
- case CTL_CH('p'):
- case CTL_CH('n'):
- {
- char * hline;
- esc_len = 0;
- if (ichar == CTL_CH('p'))
- hline = hist_prev();
- else
- hline = hist_next();
- if (!hline) {
- getcmd_cbeep();
- continue;
- }
- /* nuke the current line */
- /* first, go home */
- BEGINNING_OF_LINE();
- /* erase to end of line */
- ERASE_TO_EOL();
- /* copy new line into place and display */
- strcpy(buf, hline);
- eol_num = strlen(buf);
- REFRESH_TO_EOL();
- continue;
- }
- #ifdef CONFIG_AUTO_COMPLETE
- case '\t': {
- int num2, col;
- /* do not autocomplete when in the middle */
- if (num < eol_num) {
- getcmd_cbeep();
- break;
- }
- buf[num] = '\0';
- col = strlen(prompt) + eol_num;
- num2 = num;
- if (cmd_auto_complete(prompt, buf, &num2, &col)) {
- col = num2 - num;
- num += col;
- eol_num += col;
- }
- break;
- }
- #endif
- default:
- cread_add_char(ichar, insert, &num, &eol_num, buf, *len);
- break;
- }
- }
- *len = eol_num;
- buf[eol_num] = '\0'; /* lose the newline */
- if (buf[0] && buf[0] != CREAD_HIST_CHAR)
- cread_add_to_hist(buf);
- hist_cur = hist_add_idx;
- return 0;
- }
这些都是 ANSI 控制码 ,以ESC起始为标记,百度就知道了 。
在测试这个问题的时候,需要使用virtual box虚拟机中的xp串口进行测试,百度半天也没找到能完全说清楚的文章,下面介绍我个人的试验结果和理解:
第一种是裸文件,这种模式只能让虚拟机串口输出信息到宿主机(我的是ubuntu)的某个文件中,打开可以查看虚拟机串口发来的文字信息,基本没什么用。
第二种是主机管道,这个模式可以让主机和虚拟机进行串口通信,相当于建立一个模拟的串口通道,主机和虚拟机互联,这个模式非常有用,对于测试串口提供了很方便的测试条件,即使你电脑没有真是串口也没关系。再也不需要想办法去破解windows那些收费的虚拟串口软件了。
注意使用主机管道模式时,应在管道路径前加上前缀unix#,例如virtual box中设置了串口位置为/dev/xpserial,那么minicom中应设置Serial Device 为 unix#/dev/xpserial
第三种是主机设备,这个就相当于将真实主机绑定到虚拟机了,这时候真串口只能给虚拟机用,但是有延迟,有时候会丢数据,实际上个人认为如果只是简单数据收发没必要用这个模式,真串口给宿主机用就可以了。
F8:
ASCII 码:^[[19~
十六进制0x1b 0x5b 0x31 0x39 0x7e
第一个字节0x1b是"^[" ,第 二个字节0x5b是'[',第3个字节是0x31,第4字节就得到'9', 同理,0x39得到'9 ',最后0x7e是'~'
\033\133\061\071\176
在securecrt做映射时可以使用 "\e[\061\071\176"
↑:
^[[A
^[是第一个字节0x1b ,第二个字节0x5b是[,最后的0x41是A
0x1b 0x5b 0x41
\033\133\101
Shift + F8:
^[[19;2~
0x1b 0x5b 0x31 0x39 0x3b 0x32 0x7e
"\e[\061\071\073\062\176"
关于控制码还可以参考:
http://bbs.csdn.net/topics/320015593