天天看點

Hi3520D 序列槽使用執行個體

以下給出了一個源檔案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;
			}
		}