下面是自我测试
- | 讲述GCC编译流程与编译指令和生成的文件后缀是什么,是什么类型?
- | .c文件什么gcc指令成为.i文件; .c文件什么gcc指令成为.s文件;.c文件什么gcc指令成为.o文件
- | 如何进入gdb调试,如何使用gdb查看文件,设置断点,如何设置断点,如何查看变量值,如何单步运行,如何查看断点情况
- | main函数的标准格式是什么,第一个参数是什么意思,第二个参数是什么意思,Linux命令就是这么实现的
- | 什么函数控制led灯,蜂鸣器这些io
- | 什么是串口,什么是流控
- | 读取串口当前参数的函数是什么;提取输入波特率函数是什么;提取输入波特率函数是什么;输入输出波特率设置函数是什么;清空串口缓存的函数的声明;设置串口参数的函数是声明
- | 串口的接收与发送函数是什么
下面是知识介绍
<mark>提问:讲述GCC编译流程与编译指令和生成的文件后缀是什么,是什么类型?</mark> | <mark>GCC编译流程,i是input,所以预编译是i,o是out,所以汇编后是o;gcc就是把用户的c文件弄成二进制文件o,这些二进制文件就是字节码文件就是机器文件,机器通过识别101010来对应不同的架构内的指令进行执行(由于我们一般不叫做二进制文件,不好听,叫做目标文件,再链接其他二进制文件,组成最后的二进制文件exe</mark> |
---|---|
GCC支持的后缀 | |
分析器 | 将源代码转换为汇编语言 |
汇编器 | 将汇编语言转换为CPU可执行的字节码 |
链接器 | 将汇编器生成的单独的目标文件组合成可执行的应用程序 |
GCC命令参数 | <mark>1:-c,只对开c文件解析,最后生成二进制目标.o文件;-E就是只生成.i文件(E等于1的意思,就是只进行一步,也就是预编译;-S就是生成.s文件,s对s这个好记</mark> 2:-g 用于源代码调试代码 3:-O,优化编译;产生的可执行文件的执行效率提高,但是编译、连接的速度就相应地要慢一些。 4:-O2,比-O更好的优化效果,编译速度也更慢 6:-L 链接库 7:-E生成预处理代码 8:-S生成汇编代码 10:gcc 生成可执行文件 |
GDB调试工具 | 示例: |
---|---|
GDB命令 | |
<mark>l look查看代码</mark> | |
b 设置断点 | |
del 删除断点 | 删除第一第二个断点 |
<mark>info b 查看断点情况</mark> | |
r 运行代码 | |
printf 查看变量值 | |
n 单步运行 | |
<mark>c 退出调试,恢复程序运行</mark> | |
q 退出调试 | |
help 帮助 | |
main函数的参数 | int main(int argc,char **argv) argc = 参数的个数 **argv=存储输入字符的数组 结果验证: 为什么要对main函数进行传参,项目模块开发的时候,测试main函数功能就使用这种方式,在Linux很常见 |
字符设备控制LED灯 | 要会使用<mark>ioctl</mark>函数;注意open打开的文件是开发板dev下的leds,将用arm编译器编译好的可执行文件拷贝到TF卡中,再将TF卡挂载到开发板进行执行(如果运行时打印U盘文件系统只读,将U盘重新格式化一次即可) 验证开发板,观察到开发板的不同IO输出不同电平,对应控制两个灯开关 |
字符设备控制之蜂鸣器 | 操作过程与代码和LED灯的完全一致 |
串口编程的知识点 | 串口就是串行的接口,就是一个一个bite的接收与发送的通道,RS232就是串口;<mark>打个比方,接收到0x1111后面的数据才是真正的数据,这个过程就是流控</mark>,就是确定哪些数据有效的 (1)打开开发板串口;由于操作系统能自动识别硬件并编号,所以打开串口和打开文件一样方便 (2)串口初始化过程:先读取当前参数,修改参数,配置参数 (2.1)读取串口当前参数函数是<mark>tcgetattr(attr=attribute=属性;tc=translate control)</mark> (2.2)<mark>提取输入波特率函数;cf=控制频率,cfgetispeed=控制频率之获取输入速度</mark> (2.3)<mark>提取输出波特率函数</mark> (2.4)<mark>输入与输出波特率的设置函数</mark> (2.5)<mark>清空串口buffer中的数据的函数</mark> (2.6)<mark>设置串口参数的函数</mark> (3)串口发送与接收与对文件操作一样使用write和read函数;向串口驱动文件写入数据就是串口向外发送数据;向串口驱动文件接收数据就是串口接收发来的数据 |
开发板串口发送数据的编程实例 =============================================================================== #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> #include <errno.h> int set_opt(int,int,int,char,int);//函数声明的格式,可以先不用写参数名 void main() { int fd,wr_static,i=10; char *uart3 = "/dev/ttySAC3"; //识别的设备驱动文件 char *buffer = "hello world!\n"; printf("\r\nitop4412 uart3 writetest start\r\n"); //打开串口文件 if((fd = open(uart3, O_RDWR|O_NOCTTY|O_NDELAY))<0){ printf("open %s is failed",uart3); } else{ printf("open %s is success\n",uart3); //设置串口参数 set_opt(fd, 115200, 8, 'N', 1); //发送10次 while(i--) { //向串口文件写入数据,串口再向外发送数据 wr_static = write(fd,buffer, strlen(buffer)); if(wr_static<0) printf("write failed\n"); else{ printf("wr_static is %d\n",wr_static); } sleep(1); } } close(fd);//最后记得关闭文件描述符 } int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop) { struct termios newtio,oldtio;//串口结构体句柄 //获取串口参数信息,存放在okldtio结构体 if ( tcgetattr( fd,&oldtio) != 0) { perror("SetupSerial 1"); return -1; } //清空结构体 bzero( &newtio, sizeof( newtio ) ); //c_iflag; /* input modes */ //c_oflag; /* output modes */ //c_cflag; /* control modes */ //c_lflag; /* local modes */ //c_cc[NCCS]; /* special characters */ newtio.c_cflag |= CLOCAL | CREAD; newtio.c_cflag &= ~CSIZE; switch( nBits ) { case 7: newtio.c_cflag |= CS7; break; case 8: newtio.c_cflag |= CS8; break; } switch( nEvent ) { case 'O': newtio.c_cflag |= PARENB; newtio.c_cflag |= PARODD; newtio.c_iflag |= (INPCK | ISTRIP); break; case 'E': newtio.c_iflag |= (INPCK | ISTRIP); newtio.c_cflag |= PARENB; newtio.c_cflag &= ~PARODD; break; case 'N': newtio.c_cflag &= ~PARENB; break; } switch( nSpeed ) { case 2400: cfsetispeed(&newtio, B2400); //设置输入波特率 cfsetospeed(&newtio, B2400); //设置输出波特率 break; case 4800: cfsetispeed(&newtio, B4800); cfsetospeed(&newtio, B4800); break; case 9600: cfsetispeed(&newtio, B9600); cfsetospeed(&newtio, B9600); break; case 115200: cfsetispeed(&newtio, B115200); cfsetospeed(&newtio, B115200); break; case 460800: cfsetispeed(&newtio, B460800); cfsetospeed(&newtio, B460800); break; default: cfsetispeed(&newtio, B9600); cfsetospeed(&newtio, B9600); break; } if( nStop == 1 ) newtio.c_cflag &= ~CSTOPB; else if ( nStop == 2 ) newtio.c_cflag |= CSTOPB; newtio.c_cc[VTIME] = 0; newtio.c_cc[VMIN] = 0; tcflush(fd,TCIFLUSH); //清空串口缓冲区 //将串口结构体参数写入硬件;前面的都是写入结构体 if((tcsetattr(fd,TCSANOW,&newtio))!=0) { perror("com set error"); return -1; } return 0; } /* 下面是c_cflag参数的可选值 c_cflag flag constants: CBAUD (not in POSIX) Baud speed mask (4+1 bits). [requires _BSD_SOURCE or _SVID_SOURCE] CBAUDEX (not in POSIX) Extra baud speed mask (1 bit), included in CBAUD. [requires _BSD_SOURCE or _SVID_SOURCE] (POSIX says that the baud speed is stored in the termios structure without speci‐ fying where precisely, and provides cfgetispeed() and cfsetispeed() for getting at it. Some systems use bits selected by CBAUD in c_cflag, other systems use sepa‐ rate fields, for example, sg_ispeed and sg_ospeed.) CSIZE Character size mask. Values are CS5, CS6, CS7, or CS8. CSTOPB Set two stop bits, rather than one. CREAD Enable receiver. PARENB Enable parity generation on output and parity checking for input. PARODD If set, then parity for input and output is odd; otherwise even parity is used. HUPCL Lower modem control lines after last process closes the device (hang up). CLOCAL Ignore modem control lines. LOBLK (not in POSIX) Block output from a noncurrent shell layer. For use by shl (shell layers). (Not implemented on Linux.) CIBAUD (not in POSIX) Mask for input speeds. The values for the CIBAUD bits are the same as the values for the CBAUD bits, shifted left IBSHIFT bits. [requires _BSD_SOURCE or _SVID_SOURCE] (Not implemented on Linux.) CMSPAR (not in POSIX) Use "stick" (mark/space) parity (supported on certain serial devices): if PARODD is set, the parity bit is always 1; if PARODD is not set, then the parity bit is always 0). [requires _BSD_SOURCE or _SVID_SOURCE] CRTSCTS (not in POSIX) Enable RTS/CTS (hardware) flow control. [requires _BSD_SOURCE or _SVID_SOURCE] */ /* 下面是c_iflag的可选值 c_iflag flag constants: IGNBRK Ignore BREAK condition on input. BRKINT If IGNBRK is set, a BREAK is ignored. If it is not set but BRKINT is set, then a BREAK causes the input and output queues to be flushed, and if the terminal is the controlling terminal of a foreground process group, it will cause a SIGINT to be sent to this foreground process group. When neither IGNBRK nor BRKINT are set, a BREAK reads as a null byte ('\0'), except when PARMRK is set, in which case it reads as the sequence \377 \0 \0. IGNPAR Ignore framing errors and parity errors. PARMRK If IGNPAR is not set, prefix a character with a parity error or framing error with \377 \0. If neither IGNPAR nor PARMRK is set, read a character with a parity error or framing error as \0. INPCK Enable input parity checking. ISTRIP Strip off eighth bit. INLCR Translate NL to CR on input. IGNCR Ignore carriage return on input. ICRNL Translate carriage return to newline on input (unless IGNCR is set). IUCLC (not in POSIX) Map uppercase characters to lowercase on input. IXON Enable XON/XOFF flow control on output. IXANY (XSI) Typing any character will restart stopped output. (The default is to allow just the START character to restart output.) IXOFF Enable XON/XOFF flow control on input. IMAXBEL (not in POSIX) Ring bell when input queue is full. Linux does not implement this bit, and acts as if it is always set. IUTF8 (since Linux 2.6.4) (not in POSIX) Input is UTF8; this allows character-erase to be correctly per‐ formed in cooked mode. */ /*下面是c_clag参数的可选值 c_cflag flag constants: CBAUD (not in POSIX) Baud speed mask (4+1 bits). [requires _BSD_SOURCE or _SVID_SOURCE] CBAUDEX (not in POSIX) Extra baud speed mask (1 bit), included in CBAUD. [requires _BSD_SOURCE or _SVID_SOURCE] (POSIX says that the baud speed is stored in the termios structure without speci‐ fying where precisely, and provides cfgetispeed() and cfsetispeed() for getting at it. Some systems use bits selected by CBAUD in c_cflag, other systems use sepa‐ rate fields, for example, sg_ispeed and sg_ospeed.) CSIZE Character size mask. Values are CS5, CS6, CS7, or CS8. CSTOPB Set two stop bits, rather than one. CREAD Enable receiver. PARENB Enable parity generation on output and parity checking for input. PARODD If set, then parity for input and output is odd; otherwise even parity is used. HUPCL Lower modem control lines after last process closes the device (hang up). CLOCAL Ignore modem control lines. LOBLK (not in POSIX) Block output from a noncurrent shell layer. For use by shl (shell layers). (Not implemented on Linux.) CIBAUD (not in POSIX) Mask for input speeds. The values for the CIBAUD bits are the same as the values for the CBAUD bits, shifted left IBSHIFT bits. [requires _BSD_SOURCE or _SVID_SOURCE] (Not implemented on Linux.) CMSPAR (not in POSIX) Use "stick" (mark/space) parity (supported on certain serial devices): if PARODD is set, the parity bit is always 1; if PARODD is not set, then the parity bit is always 0). [requires _BSD_SOURCE or _SVID_SOURCE] CRTSCTS (not in POSIX) Enable RTS/CTS (hardware) flow control. [requires _BSD_SOURCE or _SVID_SOURCE] */ ==============================================================================================
串口接收例程 ======================================================================================= #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> #include <errno.h> int set_opt(int,int,int,char,int); //"/dev/ttySAC3"是con2,靠近耳机接口的串口 void main() { int fd,nByte; char *uart3 = "/dev/ttySAC3"; char buffer[512]; char *uart_out = "please input\r\n"; //清空接收缓存 memset(buffer, 0, sizeof(buffer)); //打开串口 if((fd = open(uart3, O_RDWR|O_NOCTTY))<0) printf("open %s is failed",uart3); else{ //设置串口参数 set_opt(fd, 115200, 8, 'N', 1); write(fd,uart_out, strlen(uart_out)); while(1){ //读取usart驱动文件的数据 == usart接收数据 while((nByte = read(fd, buffer, 512))>0){ buffer[nByte+1] = '\0'; write(fd,buffer,strlen(buffer)); memset(buffer, 0, strlen(buffer)); nByte = 0; } } } } int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop) { struct termios newtio,oldtio; if ( tcgetattr( fd,&oldtio) != 0) { perror("SetupSerial 1"); return -1; } bzero( &newtio, sizeof( newtio ) ); newtio.c_cflag |= CLOCAL | CREAD; newtio.c_cflag &= ~CSIZE; switch( nBits ) { case 7: newtio.c_cflag |= CS7; break; case 8: newtio.c_cflag |= CS8; break; } switch( nEvent ) { case 'O': newtio.c_cflag |= PARENB; newtio.c_cflag |= PARODD; newtio.c_iflag |= (INPCK | ISTRIP); break; case 'E': newtio.c_iflag |= (INPCK | ISTRIP); newtio.c_cflag |= PARENB; newtio.c_cflag &= ~PARODD; break; case 'N': newtio.c_cflag &= ~PARENB; break; } switch( nSpeed ) { case 2400: cfsetispeed(&newtio, B2400); cfsetospeed(&newtio, B2400); break; case 4800: cfsetispeed(&newtio, B4800); cfsetospeed(&newtio, B4800); break; case 9600: cfsetispeed(&newtio, B9600); cfsetospeed(&newtio, B9600); break; case 115200: cfsetispeed(&newtio, B115200); cfsetospeed(&newtio, B115200); break; case 460800: cfsetispeed(&newtio, B460800); cfsetospeed(&newtio, B460800); break; default: cfsetispeed(&newtio, B9600); cfsetospeed(&newtio, B9600); break; } if( nStop == 1 ) newtio.c_cflag &= ~CSTOPB; else if ( nStop == 2 ) newtio.c_cflag |= CSTOPB; newtio.c_cc[VTIME] = 0; newtio.c_cc[VMIN] = 0; tcflush(fd,TCIFLUSH); if((tcsetattr(fd,TCSANOW,&newtio))!=0) { perror("com set error"); return -1; } // printf("set done!\n\r"); return 0; } =======================================================================================