14. Serial console establishment

Publisher:Mingyue1314Latest update time:2024-11-04 Source: cnblogsKeywords:uboot Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

There are three main contents in this section of serial console establishment:

1. Console framework construction

1.1 Introduction to the classification of consoles:

1.1.1 Menu-type console: a console that executes corresponding functions after selecting the set number or letter options:

For example, the interface after entering uboot is a menu-based console:

Waiting for us to enter a command to perform the corresponding operation. For example, if we enter 1 at this time, it will format the nand flash:

1.1.2 Analytical console: In the menu console above, select 5: Exit to command line: and the following will appear:

Enter the analytical console:

After we enter help, the console will analyze whether this command is supported by the console. If it is, it will call the corresponding help function to run it. The commands supported by the parsing console where the uboot is located will be listed:

Since the parsing console is complicated to implement, today we will choose a relatively simple menu-based console to implement a relatively simple uboot console of our own.

Menu-based console:

You can see a menu console. The first thing to do is to print out the menu, and it will print in a loop. The first thing that comes to mind is to use printf to print the menu information. Code:

The above is the prompt information in uboot. The corresponding function is executed according to the user's option, and the implementation is selected through switch. The above is the menu frame.

In the implementation of the menu-type console above, the two most important functions are scanf and printf.

2. Implementation of scanf and printf

First, implement the printf function. When implementing a function, the first thing to consider is its function. The function of printf is to print information. In a PC, printf prints information to the display. However, in the development board, printf prints information to the serial terminal. Next, we need to understand the parameters of the function. To understand its parameters, we need to execute man 3 printf in the command line:

You can see that the first one is our printf function, but its parameters are variable parameters, which are represented by three dots, which means that the parameters of this function are not fixed. It can be zero, one, or many. The form of the following variable parameters is determined by the preceding const char *format. That is, if const char *format specifies an integer parameter, then... it must be an integer parameter, and if const char *format is a character parameter, then... it must be a character parameter.

Implementation idea: Convert the incoming parameters into a string buffer, and then output the string buffer to the serial port terminal through a while loop using the void putc(unsigned char ch) function implemented in the previous section.

The difficulty in implementing this idea is how to convert the incoming parameters into a string buffer.

1) Create a printf.c in the uboot project in the previous section:

2) Then add printf.c to the Makefile:

3) Implementation of printf.c: (1) Convert variable parameters to strings. (2) Print the strings to the serial port.

For (2) printing a string to the serial port, it is easy to implement at the beginning because the putc() function has been implemented before:

The difficult part is (1) converting the variable parameter into a string. Here we need to use some macros that have been implemented in C language. Some macros (functions) about variable parameter processing. Let us complete it. (1) Convert the variable parameter into a string. Implementation steps:

The above has realized the conversion of variable parameters into strings. But the problem comes again. The three macros (functions) above have to be implemented by us, and the implementation is very complicated and very standard. Here we can use the transplantation method.

When we implement this kind of embedded software, it does not mean that we need to write all the codes by ourselves. For example, we need to implement TFTP later, and TFTP also needs IP protocol stack, but we cannot implement IP protocol stack. So when implementing embedded software, we need to transplant it a lot.

There are two places where we can implement the transplantation, one is in the Linux kernel, or in the C library. When it comes to transplantation, it is too difficult for us at this stage. So now we just need to know what the functions of these three functions are, and how to use these files extracted from the Linux kernel and integrate them into our own uboot project.

Below are two extracted file directories:

Copy these two folders to the original project directory:

Next, modify the Makefile in the project folder as follows:

Before modification:

Revise:

  1. Put printf.c in the lib folder, and compile lib.o in the lib folder together, then you need to include lib/lib.o. So replace printf.o with lib/lib.o.

  2. Then, gboot.bin is obtained using gboot.elf.

  1. gboot.elf is obtained by linking the above *.o files.

  1. In order to get lib/lib.o, you need to enter the lib folder to compile. The result of make is to get all:

All is the file obtained after make in the lib folder:

  1. Also enter the lib folder to clean:

The last modified file is:

Makefile under lib:

The top-level Makefile is:

After the modification, compile make and the following error will be reported:

The ctype.c file above is in the lib folder. The error here means that the file in the lib folder has been used in the gboot.bin project, but an error is reported. The error message is that there are many undefined symbols in ctype.c. Next, open ctype.c and see what is going on:

As we can see above, these symbols are used in ctyp.c. Why does make report that these symbols are not defined? You can see that it includes the ctype.h header file, open it:

You can see that these symbols have been defined in include/ctype.h. You can see that these symbols have been defined in ctype.h. The problem is that when compiling, the arm-linux-gcc compiler defaults to the path where the header file is found, and does not find the include/ctype.h header file in our current project. This requires us to specify the compiler arm-linux-gcc to find the header file in the path we specify in addition to the default path when compiling. To specify the header file path yourself, use the -I parameter to specify the path to find the header file.

Open the Makefile in the lib directory:

Here, we need to add -I after the arm-linux-gcc name to specify the path to the header file. But you can see that there is already a CFLAGS variable, which is used to save some compilation parameters. CFLAGS is defined in the Makefile in the project folder:

Open the top-level Makefile and add the definition of CFLAGS:

The value of the CFLAGS variable is a path. The current relative path is obtained through the shell command pwd, including the include folder under the path. In order for the underlying directory to use the file, the variable needs to be exported:

After modification, make, the previous problem is solved:

You can see that the previous problem is solved, but a new problem has arisen: va_list in line 3 of printf.c is not defined. Open printf.c:

The above type va_list is defined in the lib/vsprintf.h file:

So to solve this error, just include lib/vsprintf.h into printf.c:

After adding it, compile make and you will get the following error:

The first warning is uart.c:29: warning: conflicting types for built-in function 'putc'. Then I open line 29 of uart.c and find that there is no built-in function at all. This is because there is a missing parameter in the Makefile: -fno-builtin

Then add the variable CFLAGS to the Makefile where the c file is compiled:

Recompile:

You will find that the warning is gone. There is an error again. It is that when compiling lib/lib.o, it is found that vaprintf is undefined. Oh, this is because our function is written incorrectly, it should be vsprintf. After modification:

After modification, make again: the original error still exists:

Logically, this error should not occur again after the modification. Besides, there is no trace of vaprintf in the project now. Why is it still the same error? No matter how I make clean and then make, the same error still occurs. I am helpless and ask Baidu for help, but Baidu has no solution. Finally, after make clean, I enter the lib folder and find that the generated things in the lib folder have not been cleared. I make clean in the lib folder and then return to the original project directory, make clean, and a miracle happens:

But there is still an error, which is caused by the scanf function we defined and implemented:

Let's comment it out first:

After the modification, the recompilation was successful:

gboot.bin is generated:

After burning to the development board, I found that the content of the serial terminal was output:

The printf function is implemented above, and the next step is to implement the scanf function. In Redhat 6.4, execute the command: man 3 scanf:

You can see that the return value is int, the first parameter is const char *format, and the second parameter is still a variable parameter. The implementation process of this function is the opposite of printf. The Scanf function is: 1) Get the input string first. 2) Get the string, convert the format, and pass it to the system. Implementation code:

Compilation successful:

At this point, printf and scanf are both implemented, compiled and burned to the development board:

We can see that the input effect we want appears. When we input 1, there is no response. When we input 4, Error: wrong is output.

[1] [2]
Keywords:uboot Reference address:14. Serial console establishment

Previous article:15.210 Console Fault Analysis (Ideas for Solving Problems)
Next article:13. Smart210 serial port driver based on 12 supplement

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号