以下給出了一個源檔案uart.c和makefile檔案,在 sdk/mpp/sample/ 底下建立一個檔案夾,随便命名,現在命名為UartTest,再把uart.c和makefile拷貝進去,編譯
此外,還需要把 libjpeg.so libmpi.so libtde.so 放入核心闆 /lib目錄下;
所有的檔案拷貝完成後 運作 ./uart /dev/ttyAMA2 0
源檔案 uart.c
/*
* uart_gkwzt.c
*
* Created on: 2012-10-15
* Author: root
*/
#include <stdio.h> /* 标準輸入輸出定義 */
#include <stdlib.h> /* 标準函數庫定義 <span style="white-space:pre"> </span>*/
#include <unistd.h> /* Unix标準函數定義 <span style="white-space:pre"> </span>*/
#include <sys/types.h> /* */
#include <sys/stat.h> /* */
#include <fcntl.h> /* 檔案控制定義 <span style="white-space:pre"> </span>*/
#include <termios.h> /* PPSIX終端控制定義 <span style="white-space:pre"> </span>*/
#include <errno.h> /* 錯誤号定義 */
#include <string.h>
#include "mpi_sys.h"
#include "hi_comm_sys.h"
#include "hi_io.h"
#include "hi_tde_api.h"
#define TRUE 1
#define FALSE 0
/*
**********************************************************************************************************
*寄存器基位址映射
**********************************************************************************************************
*/
#define IOCFG_BASE_ADDR 0x200F0000 /* IO口複用寄存器位址空間映射 */
#define GPIO0_BASE_ADDR 0x20150000 /* GPIO0的位址空間映射 */
#define GPIO1_BASE_ADDR 0x20160000 /* GPIO1的位址空間映射 */
#define GPIO2_BASE_ADDR 0x20170000 /* GPIO2的位址空間映射 */
#define GPIO3_BASE_ADDR 0x20180000 /* GPIO3的位址空間映射 */
#define GPIO4_BASE_ADDR 0x20190000 /* GPIO4的位址空間映射 */
#define GPIO5_BASE_ADDR 0x201A0000 /* GPIO5的位址空間映射 */
#define GPIO6_BASE_ADDR 0x201B0000 /* GPIO6的位址空間映射 */
#define GPIO7_BASE_ADDR 0x201C0000 /* GPIO7的位址空間映射 */
#define GPIO8_BASE_ADDR 0x201D0000 /* GPIO7的位址空間映射 */
int speed_arr[] = {B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B300};
int name_arr[] = {115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 300};
/*
**********************************************************************************************************
*說 明:設定波特率,資料位,停止位,奇偶校驗位
*入口參數:
*出口參數:
**********************************************************************************************************
*/
int wzt_SetSerialParameter(int fd, int baudrate, int databits, int stopbits, int parity)
{
struct termios scmTermios ;
if(tcgetattr(fd,&scmTermios) != 0){
perror("Get serial parameter error");
return(FALSE);
}
/* 設定波特率 */
int i = 0;
for(i = 0; i < sizeof(speed_arr)/sizeof(int); i++){
if(baudrate == name_arr[i]){
tcflush(fd, TCIOFLUSH); /* 清除輸入輸出緩沖區 */
if(0 != cfsetispeed(&scmTermios,speed_arr[i])){ /* 設定輸入波特率 成功傳回0 否則-1 */
printf("ERROR:Set input Serial baudrate fail\n");
}
if(0 != cfsetospeed(&scmTermios,speed_arr[i])){ /* 設定輸出波特率 成功傳回0 否則-1 */
printf("ERROR:Set output Serial baudrate fail\n");
}
break;
}
}
/* 設定資料位 */
scmTermios.c_cflag &= ~CSIZE; /* 清零 */
switch (databits){
case 7: scmTermios.c_cflag |= CS7; break;
case 8: scmTermios.c_cflag |= CS8; break;
default:fprintf(stderr,"Unsupported data size\n");return (FALSE);
}
/* 設定停止位 */
switch(stopbits){
case 1: scmTermios.c_cflag &= ~CSTOPB; break;
case 2: scmTermios.c_cflag |= CSTOPB; break;
default:fprintf(stderr,"Unsupported stop bits\n");return (FALSE);
}
/* 奇偶校驗位 */
switch (parity){
case 'n':
case 'N':
scmTermios.c_cflag &= ~PARENB;
scmTermios.c_iflag &= ~INPCK;
break;
case 'o':
case 'O':
scmTermios.c_cflag |= (PARODD | PARENB);
scmTermios.c_iflag |= INPCK;
break;
case 'e':
case 'E':
scmTermios.c_cflag |= PARENB;
scmTermios.c_cflag &= ~PARODD;
scmTermios.c_iflag |= INPCK;
break;
case 'S':
case 's':
scmTermios.c_cflag &= ~PARENB;
scmTermios.c_cflag &= ~CSTOPB;
break;
default:
fprintf(stderr,"Unsupported parity\n");
return (FALSE);
}
if(parity != 'n') scmTermios.c_iflag |= INPCK;
scmTermios.c_cc[VTIME] = 150; /* 非規範模式讀取時的逾時時間 */
scmTermios.c_cc[VMIN] = 0; /* 非規範模式讀取時的最小字元數 */
tcflush(fd, TCIOFLUSH); <span style="white-space:pre"> </span>/* 清除輸入輸出緩沖區 */
if (tcsetattr(fd,TCSANOW,&scmTermios) != 0){ <span style="white-space:pre"> </span>/* 不等資料傳輸完畢就立即改變屬性 <span style="white-space:pre"> </span>*/
perror("Set serial parameter error");
return (FALSE);
}
else{
printf("MSG :Set serial parameter successfully!\n");
}
return (TRUE);
}
/*
**********************************************************************************************************
*說 明:标準輸入模式,顯示輸入字元
*入口參數:
*出口參數:
**********************************************************************************************************
*/
void wzt_DisableTerminalReturn(int fd)
{
struct termios scmTermios;
tcgetattr(fd, &scmTermios);
scmTermios.c_lflag &= ~(ICANON | ECHO);
tcsetattr(fd, TCSANOW, &scmTermios);
}
/*
**********************************************************************************************************
*說 明:gpio 複用寄存器初始化,如果在核心中複用過,在這個地方就不需要配置
*入口參數:
*出口參數:
**********************************************************************************************************
*/
void gpio_cfg_init(void)
{
HI_S32 byregval = 0;
HI_MPI_SYS_SetReg(IOCFG_BASE_ADDR+0x050,0x01); /* 設定GPIO5_1為UART1_RXD */
HI_MPI_SYS_SetReg(IOCFG_BASE_ADDR+0x058,0x01); /* 設定GPIO5_3為UART1_TXD */
HI_MPI_SYS_SetReg(IOCFG_BASE_ADDR+0x05C,0x01); /* 設定GPIO5_4為UART2_RXD */
HI_MPI_SYS_SetReg(IOCFG_BASE_ADDR+0x060,0x01); /* 設定GPIO5_5為UART2_TXD */
HI_MPI_SYS_SetReg(IOCFG_BASE_ADDR+0x0B8,0x01); /* 設定GPIO1_0為UART3_TXD */
HI_MPI_SYS_SetReg(IOCFG_BASE_ADDR+0x0BC,0x01); /* 設定GPIO1_1為UART3_RXD */
}
/*
**********************************************************************************************************
*說 明:主函數
*入口參數:
*出口參數:
*備 注:LED燈閃爍
**********************************************************************************************************
*/
int main(int argc, char** argv, char *envp[])
{
if(argc<3){
printf("*****************************************************\n");
printf("if argv[2] = 0,function: uart test \n");
printf("Usage: filename /dev/ttyAMAn 0\n");
printf("*****************************************************\n");
exit(0);
}
int action = atoi(argv[2]);
if(action==0){
gpio_cfg_init();
printf("Devices:%s\n",argv[1]);
int Ctrlfd = open(argv[1], O_RDWR);
if(-1 == Ctrlfd){
Ctrlfd = 0;
printf("Can't Open Serial Port!\n");
return 0;
}
wzt_SetSerialParameter(Ctrlfd, 115200, 8, 1, 'N');
wzt_DisableTerminalReturn(Ctrlfd);
int n=0,ret;
char buffer[1024];
char cmd[12];
for(n=0;n<10;n++){cmd[n]='0'+n;}cmd[10] = '\r';cmd[11] = '\n';
while(1){
cmd[0]='0'+(n++)%8;
ret = write(Ctrlfd,cmd,12);
int count = read(Ctrlfd,buffer,sizeof(buffer));
if(count>0){
buffer[count] = '\0';
printf("Read:%s\n",buffer);
}
else{
printf("Read:%d\n",count);
}
usleep(20000);
}
return 0;
}
exit(0);
}
Makefile 檔案(其實就是在SDK/mpp/sample/ 底下随便找個例程把其中的makefile直接拿來用就行)
# Hisilicon Hi3516 sample Makefile
include ../Makefile.param
#ifeq ($(SAMPLE_PARAM_FILE), )
# SAMPLE_PARAM_FILE:=../Makefile.param
# include $(SAMPLE_PARAM_FILE)
#endif
# target source
SRC := $(wildcard *.c)
OBJ := $(SRC:%.c=%.o)
TARGET := $(OBJ:%.o=%)
.PHONY : clean all
all: $(TARGET)
MPI_LIBS := $(REL_LIB)/libmpi.a
MPI_LIBS += $(REL_LIB)/libhdmi.a
$(TARGET):%:%.o $(COMM_OBJ)
$(CC) $(CFLAGS) -lpthread -lm -o $@ $^ $(MPI_LIBS) $(AUDIO_LIBA) $(JPEGD_LIBA)
clean:
@rm -f $(TARGET)
@rm -f $(OBJ)
@rm -f $(COMM_OBJ)
cleanstream:
@rm -f *.h264
@rm -f *.jpg
@rm -f *.mjp
@rm -f *.mp4
實際工程并不直接使用read函數讀取序列槽資料,使用 select函數 配合,部分代碼如下
/*
**************************************************************************************************
**功能描述: 設定序列槽接受資料為 select 方式
**入口參數: @fd --- -打開的序列槽檔案句柄 -
**出口參數: 傳回-1接收錯誤; 傳回0接收逾時; 傳回>0接收到資料
**-------------------------=------------------------------------
**函數注釋: xx_uart_select(fd);
**************************************************************************************************
*/
static int xx_uart_select(int fd)
{
fd_set fs;
struct timeval tmp_time;
/* 清除描述詞組fs的全部位 */
FD_ZERO(&fs);
/* 設定描述詞組fs中相關fd的位 */
FD_SET (fd, &fs);
/* 設定序列槽 100ms 等待逾時 */
tmp_time.tv_sec = 0;
tmp_time.tv_usec = 100000;
/* 使用select實作序列槽的多路通信 */
return select(fd+1, &fs, NULL, NULL, &tmp_time);
}
/* 調用方式 */
err = xx_uart_select(uart_ptr->fd);
if(-1 == err)
{
/* 接收錯誤 */
continue;
}
else if (0 == err)
{
//xxlog_trace(DBG_FALSE, "uart select timeout\n");
/* 接收逾時 */
if(0 == new_flag) {continue;}
else {len = 0; }
}
else
{
/* 接收正常 */
len = read(uart_ptr->fd, &recv_ptr[cnt], (RECV_BUFF_LEN - cnt));
cnt += len;
new_flag = 1;
/* 接收緩沖區未滿 */
if(RECV_BUFF_LEN != cnt)
{
/* 結束本次循環,從while(1)開始執行 */
continue;
}
}