I don't know if I am still using the custom data printing function to print the strings? For example:
- Uart_putstring (const char * Str );
- Uart_putchar (char ch );
- Uart_getchar ();
- Uart_getstring (char * Str );
In fact, many functions we need have been encapsulated for me in the C standard input/output library file. We can use them as long as we make a simple transplant. In the library, we can use: format the input and output functions. Such as puts (), printf (), putchar (), getchar (), and scanf.
We have to do exactly two points:
- Implement the putchar () and getchar () functions. Tell the database how to output your data and how to input it.
- Add # include <stdio. h> and call the library function.
However, I am developing a program under stm32. The database does not provide putchar () and getchar () functions. But:
- Int fputc (int ch, file * file)
- Int fgetc (File * file)
The file struct is not defined in stdio. h. However, there is a type of open reputation. Specifically, the programmer needs to define it according to his own needs.
For the development of Small embedded systems, you may not think of the "file" level. In fact, the file here does not fully refer to the Unit for storing data. It can be a device, such as a display, keyboard, serial port input and output. These devices can all be used as files. We only need to distinguish different files by file, and we can collect the corresponding output input mode for different files. In this way, file makes my extended space larger.
Here, I mainly want to use standard input and output as the serial port input and output interface. Then, we can define the file as a serial file structure. Writing data to a serial file is equivalent to sending data to the serial port.
# Define file_option_console 0x01
Struct _ file {
Void (* output) (char); // output function
Char (* input) (); // Input Function
OS _event * semaphore; // data receiving semaphore
Slock_t slock; // serial port lock
Bool ispending; // the ID of the read data wait.
Int16u time_out; // timeout
Int8u option; // Option
Int8u errno; // error code
};
Typedef struct _ file;
The definition of the above file struct. I define an output and input function pointer for each file to tell fputc and fgetc how to output and obtain data. Other fputc and fgetc do not care. You only need to tell us what to do.
Therefore, the fputc function is implemented as follows:
Int fputc (int ch, file * file)
{
If (file & file-> output) {// check the validity of the file
File-> output (CH );
}
Return ch;
}
However, when we use putchar ('\ n'), we want a line break and return to the beginning of the line. We want to output '\ R' before outputting' \ n '. Therefore, we modify fputc:
Int fputc (int ch, file * file)
{
If (file & file-> output) {// check the validity of the file
If ('\ n' = CH ){
File-> output ('\ R ');
}
File-> output (CH );
}
Return ch;
}
We cannot do this all. For hexadecimal data output, we do not need to do this. Therefore, the option is added to the file structure. If a value of 1 is used, this function is enabled. Otherwise, no processing is performed.
Int fputc (int ch, file * file)
{
If (file & file-> output) {// check the validity of the file
If (file_option_console & file-> Option) & '\ n' = CH) {// you can only use this function on the console.
File-> output ('\ R ');
}
File-> output (CH );
}
Return ch;
}
Because we have implemented a multi-task operating system. Multiple tasks may call fputc () at the same time. Therefore, we 'd better lock it.
Int fputc (int ch, file * file)
{
If (file & file-> output) {// check the validity of the file
Spin_lock (& file-> slock, 1, 0 );
If (file_option_console & file-> Option) & '\ n' = CH) {// you can only use this function on the console.
File-> output ('\ R ');
}
File-> output (CH );
Spin_unlock (& file-> slock, 1 );
}
Return ch;
}
In this step, we can easily use fputc (), fputs (), fprintf (), and so on.
So how can we achieve this?