A serial port knowledge base
- TTL level
TTL is Transistor-Transistor Logic, the abbreviation of Transistor-Transistor Logic, which is a standard technology for communication between various parts of equipment controlled by a computer processor. TTL level signal is widely used because its data representation adopts binary regulations, +5V is equivalent to logic "1", and 0V is equivalent to logic "0".
In digital circuits, the level of the circuit composed of TTL electronic components is a voltage range, which stipulates:
output high level>=2.4V, output low level <=0.4V;
input high level>=2.0V, input low power Ping<=0.8V.
2. RS232 level
RS232 level is a standard for serial ports.
On the TXD and RXD data lines:
(1) Logic 1 is a voltage of -3~-15V
(2) Logic 0 is a voltage of 3~15V On the
control lines of RTS, CTS, DSR, DTR and DCD:
(1) The signal is valid (ON state) is a voltage of 3~15V
(2) The signal is invalid (OFF state) is a voltage of -3~-15V
This is regulated by the communication protocol RS-232.
RS-232: Standard serial port, the most commonly used serial communication interface. There are three types (A, B and C), which use different voltages to represent on and off. The most widely used is RS-232C, which defines the mark (on) bit voltage as between -3V and -12V, and the space (off) voltage as between +3V and +12V. The maximum transmission distance is about 15 meters, and the maximum speed is 20kb/s. RS-232 is designed for point-to-point (that is, only a pair of receiving and sending devices) communication, and its driver load is 3-7kΩ. So RS-232 is suitable for communication between local devices.
Second, implement the printf function for bare metal debugging from scratch
- printf is a standard library function, the function is: print (variable, string) and so on.
Question: Can you write a simple my_printf function for bare-metal program debugging based on the principle of printf? - Function prototype
//====================================================
//printf的声明
int printf(const char *format, ...);
//format:固定参数
//... :可变参数(变参)
- The function uses
the format characters in the example printf
- variable parameter
1) Review of c language pointer
2) Code: Manually determine variable parameters
①Function callpush_test("abcd",123);
int push_test(const char *format, ...)
{
char *p = (char *)&format;
//参数1
printf("arg1 : %s\n",format);
//参数2
p = p + sizeof(char *);
i = *((int *)p);
printf("arg2 : %d\n",i);
...
}
②Function call
struct person{
char *name;
int age;
char score;
int id;
};
struct person per={
"www.100ask.org",10,'A',123};
push_test("abcd",123,per);
How to implement the push_test
function?
int push_test(const char *format, ...)
{
char *p = (char *)&format;
int i;
struct person per;
printf("arg1 : %s\n",format);
//==============
/*指针对连续空间操作时: 1) 取值 2)移动指针*/
p = p + sizeof(char *);
i = *((int *)p);
printf("arg2 : %d\n",i);
//==============
/*指针对连续空间操作时: 1) 取值 2)移动指针*/
p = p + sizeof(int);
per = *((struct person *)p);
printf("arg3: .name = %s, .age = %d, .socre=%c .id=%d\n",\
per.name, per.age, per.score, per.id);
}
③Because under the x86 (32-bit machine) platform, the GCC compiler defaults to 4-byte alignment,
such as: the structure is aligned with 4 bytes, that is, the memory address of the structure member variable is an integer multiple of 4.
The specified alignment size can be set by using the __attribute__ option in gcc.
struct person{
char *name;
int age;
char score;
int id;
};
/*1):__attribute__ ((packed)),让所作用的结构体取消在编译过程中的优化对齐,
按照实际占用字节数进行对齐。
*/
struct person1{
char *name;
int age;
char score;
int id;
}__attribute__ ((packed));
/*2):__attribute((aligned (n))),让所作用的结构体成员对齐在n字节边界上。
如果结构体中有成员变量的字节长度大于n,则按照最大成员变量的字节长度来对齐。
*/
struct person2{
char *name;
int age;
char score;
int id;
}__attribute((aligned (4)));
④In the process of variable parameter transfer: floating-point numbers are transferred as double variables by default.
3) Code: Automatically determine variable parameters