⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uesverify.c

📁 在嵌入式系统中对Lattice CPLD软件升级时所需的VME文件生成所需源代码。将一个链上的不同厂家的CPLD产生的SVF文件转换成VME文件
💻 C
字号:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <malloc.h>
#include "Utilities.h"
#include "UESVerify.h"

int CreateVerifyUESFile( char * a_szSVFFilename, char * a_szVMEFilename, char * a_szErrorMessage )
{
	int iIndex = 0;
	int iIDCodeCount = 0;
	int iUSERCODEInstrFound = 0;
	int iFoundIDCodeFlag = 0;
	int iRetCode = 0;
	char * pszTmp = NULL;
	char szTemporarySVFFilename[ 1024 ] = { 0 };
	char szTemporaryPath[ 1024 ] = { 0 };
	char szReadLine[ 1024 ] = { 0 };
	char szOrigReadLine[ 1024 ] = { 0 };
	FILE * fptrReadSVF = NULL;
	FILE * fptrWriteSVF = NULL;

	iRetCode = IsSynchronizeSequentialSVF( a_szSVFFilename, a_szErrorMessage );
	if ( iRetCode != 0 ) {
		return ( iRetCode );
	}

	/* Get the temporary file name */
	strcpy( szReadLine, a_szSVFFilename );
	pszTmp = strrchr ( szReadLine, FILE_SEP_CHAR );
	if ( pszTmp ) {
		pszTmp++;
		strcpy( szTemporarySVFFilename, pszTmp );
		szTemporarySVFFilename[ strlen( szTemporarySVFFilename ) - 4 ] = '\0';
		strcat( szTemporarySVFFilename, "$$$.svf" );
	}
	else {
		strcpy( szTemporarySVFFilename, szReadLine );
		szTemporarySVFFilename[ strlen( szTemporarySVFFilename ) - 4 ] = '\0';
		strcat( szTemporarySVFFilename, "$$$.svf" );
	}

	/* Get the temporary file path */
	strcpy( szTemporaryPath, a_szVMEFilename );
	pszTmp = strrchr( szTemporaryPath, FILE_SEP_CHAR );
	if ( pszTmp ) {
		*pszTmp = '\0';
		strcat( szTemporaryPath, FILE_SEP );
		strcat( szTemporaryPath, szTemporarySVFFilename );
		strcpy( szTemporarySVFFilename, szTemporaryPath );
	}

	fptrReadSVF = fopen( a_szSVFFilename, "r" );
	if ( fptrReadSVF == NULL ) {
		sprintf( a_szErrorMessage, "Error: svf file %s cannot be read.\n\n", a_szSVFFilename );
		return ( FILE_NOT_VALID );
	}
	
	/* Count the number of ID code checks.  This will indicate the potential
	   number of USERCODE verification instructions                          */
	while( !feof( fptrReadSVF ) ) {
		fgets( szReadLine, 1024, fptrReadSVF );
		TrimLeft( szReadLine );
		TrimRight( szReadLine );
		if ( !stricmp( szReadLine, "! Check the IDCODE" ) ) {
			iIDCodeCount++;
		}
	}

	if ( iIDCodeCount <= 0 ) {
		fclose( fptrReadSVF );
		return ( MISSING_IDCODE_COMMENTS );
	}

	/* Allocate memory to hold the UES array */
	if ( ( uesVerifyArray = ( SUESVerify * ) calloc( iIDCodeCount + 1, sizeof( SUESVerify ) ) ) == NULL ) {
		fclose( fptrReadSVF );
		return ( OUT_OF_MEMORY );
	}

	/* Default UESLines */
	for ( iIndex = 0; iIndex < iIDCodeCount; iIndex++ ) {
		strcpy( uesVerifyArray[ iIndex ].szUESLine, "" );
	}

	/* Search for UES instructions in the SVF file */
	iIndex = -1;
	rewind( fptrReadSVF );
	while( !feof( fptrReadSVF ) ) {
		fgets( szReadLine, 1024, fptrReadSVF );
		TrimLeft( szReadLine );
		TrimRight( szReadLine );
		/* When erase instruction is found, increment the index to denote the device.
		   This is necessary because not all erase instructions will be paired with
		   a verify USERCODE instruction ( i.e. not every device has a USERCODE )     */
		if ( !stricmp( szReadLine, "! Check the IDCODE" ) ) {
			iIndex++;
		}
		else if ( szReadLine[ 0 ] == '!' ) {
			strlwr( szReadLine );
			/* Checking is done this way because ispVM writes two types of USERCODE  
			   verification comments:                                    
					1) "! Verify USERCODE"
					2) "!Verify USERCODE"                                           */
			if ( strstr( szReadLine, "verify" ) && strstr( szReadLine, "usercode" ) ) {
				iUSERCODEInstrFound++;
				GetUESInstructions(	szReadLine, fptrReadSVF );
				strcpy( uesVerifyArray[ iIndex ].szUESLine, szReadLine );
			}
		}
	}

	if ( iUSERCODEInstrFound <= 0 ) {
		fclose( fptrReadSVF );
		free( uesVerifyArray );
		return ( MISSING_UES_COMMENTS );
	}

	fptrWriteSVF = fopen( szTemporarySVFFilename, "w" );
	if ( fptrWriteSVF == NULL ) {
		fclose( fptrReadSVF );
		free( uesVerifyArray );
		return ( -1 );
	}
	
	/* Copy SVF to temporary SVF, and insert USERCODE instructions before the erase insructions */
	iIndex = 0;
	rewind( fptrReadSVF );
	while( !feof( fptrReadSVF ) ) {
		fgets( szOrigReadLine, 1024, fptrReadSVF );

		strcpy( szReadLine, szOrigReadLine );
		TrimLeft( szReadLine );
		TrimRight( szReadLine );
		if ( !stricmp( szReadLine, "! Check the IDCODE" ) ) {
			/* Turn on flag */
			iFoundIDCodeFlag = 1;
		}
		else if ( iFoundIDCodeFlag && szReadLine[ 0 ] == '!' ) {
			if ( stricmp( uesVerifyArray[ iIndex ].szUESLine, "" ) ) {
				sprintf( szReadLine, "! Continue if fail\n" );
				fprintf( fptrWriteSVF, szReadLine );

				/* Write verify UES opcode */
				sprintf( szReadLine, "VUES\n" );
				fprintf( fptrWriteSVF, szReadLine );

				fprintf( fptrWriteSVF, uesVerifyArray[ iIndex ].szUESLine );
			}
			iIndex++;
			/* Turn off flag */
			iFoundIDCodeFlag = 0;
		}

		/* Copy over original SVF */
		if ( feof( fptrReadSVF ) ) {
			break;
		}
		fprintf( fptrWriteSVF, szOrigReadLine );
	}

	/* Free UES array memory */
	free( uesVerifyArray );

	/* Close file pointers */
	fclose( fptrReadSVF );
	fclose( fptrWriteSVF );
	
	/* Copy temporary SVF file name as the SVF to be converted to VME */
	strcpy( a_szSVFFilename, szTemporarySVFFilename );
	
	return OK;
}

void GetUESInstructions( char * a_pszUESLine, FILE * fptrReadSVF )
{
	int iUESLineIndex = 0;
	char cReadChar = 0;
	char szUESLine[ 1024 ] = { 0 };
	
	if ( feof( fptrReadSVF ) ) {
		return;
	}

	if ( !a_pszUESLine ) {
		return;
	}

	/* Retrieve the USERCODE instructions until it finds the next comment */
	while( !feof( fptrReadSVF ) ) {
		cReadChar = fgetc( fptrReadSVF );
		if ( cReadChar == '!' || cReadChar == '/' ) {
			break;
		}
		szUESLine[ iUESLineIndex++ ] = cReadChar;
	}

	strcpy( a_pszUESLine, szUESLine );
}

int IsSynchronizeSequentialSVF( char * a_szSVFFilename, char * a_szErrorMessage )
{
	int iEraseDeviceCount = 0;
	int iCheckIDCount = 0;
	char szReadLine[ 1024 ] = { 0 };
	FILE * fptrReadSVF = NULL;

	fptrReadSVF = fopen( a_szSVFFilename, "r" );
	if ( fptrReadSVF == NULL ) {
		return -1;
	}

	while( !feof( fptrReadSVF ) ) {
		fgets( szReadLine, 1024, fptrReadSVF );
		TrimLeft( szReadLine );
		TrimRight( szReadLine );
		if ( !stricmp( szReadLine, "! Erase the device" ) ) {
			iEraseDeviceCount++;
		}
		else if ( !stricmp( szReadLine, "! Check the IDCODE" ) ) {
			iCheckIDCount++;
		}
	}
	fclose( fptrReadSVF );

	if ( iEraseDeviceCount == 0 ) {
		sprintf( a_szErrorMessage, "Error: svf file %s does not appear to be an Erase, Program, Verify SVF.\n\n", a_szSVFFilename );
		return ERR_NON_EPV_SVF;
	}

	/* If the number of ID code checks does not equal the number of erase counts,
	   then return an error because this assumes the SVF file has been generated
	   with synchronize turned on.                                                */
	if ( iEraseDeviceCount != iCheckIDCount ) {
		return SYNCHRONIZE_SVF;
	}

	return OK;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -