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

📄 fls_jrnl.c

📁 一款收款机C源代码!因为是几年前的代码了
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * Module: Fls_Jrnl.C
 * Modified by: X.C.Zheng WeiHua
 * Modified on: Date:  2004-08-23 18:35
 * Copyright(c) WeiHua Tech Ltd.
 */


/* Detail:
	This file contains some routines of the journal in flash I/O functions and some  algorithm
	of the journal operating functions.
	注: 由于时间关系, 这里的从程序写得比较混乱, 但是有一些多余的东西还没有进行删除, 还有就是在读取Flash内容的时候
		 是直接读取的, 而没有调用函数来进行完成.
*/

#include "ecrsys.h"
#include "data.h"
#include "ftype.h"
#include <stdlib.h>
#include <string.h>


#ifdef	ELEC_JRNL
ELECJRNLHEADDEF	fls_head_jrnl;

const byte			log_legal_order[] = {
	#ifdef	DEBUG_TEST
	0x50,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xA5,0x00
	#else
	0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xA5,0x00
	#endif
};


/* 
	Judge existing the active log or not.
	The active log legal order is:
		55 AA 55 AA 55 AA 55 AA 55 AA 55 AA 55 AA 55 AA.(16 bytes)
*/
BOOL	Atv_Log_Judge(void)
{
	byte	i;
	byte	temp;
	byte	*jrnl_atv_addr = (byte *)JRNL_ATV_ADDR;

	for(i = 0; i < 16; i ++)
	{
		temp = jrnl_atv_addr[i];
		if(temp != log_legal_order[i])
			return (FALSE);
	}
	return (TRUE);
}

/* Get the next logic sector, it is universal for the three electronic journal */
byte	*Get_Next_Logic_Sector(byte *elec_jrnl_ptr)
{
	if(elec_jrnl_ptr == (byte *)FLS_SCT02_ADDR)
		elec_jrnl_ptr = (byte *)FLS_SCT03_ADDR;
	else if(elec_jrnl_ptr == (byte *)FLS_SCT03_ADDR)
		elec_jrnl_ptr = (byte *)FLS_SCT04_ADDR;
	else if(elec_jrnl_ptr == (byte *)FLS_SCT04_ADDR)
		elec_jrnl_ptr = (byte *)FLS_SCT02_ADDR;

	else if(elec_jrnl_ptr == (byte *)FLS_SCT05_ADDR)
		elec_jrnl_ptr = (byte *)FLS_SCT06_ADDR;
	else if(elec_jrnl_ptr == (byte *)FLS_SCT06_ADDR)
		elec_jrnl_ptr = (byte *)FLS_SCT05_ADDR;

	else if(elec_jrnl_ptr == (byte *)FLS_SCT07_ADDR)
		elec_jrnl_ptr = (byte *)FLS_SCT08_ADDR;
	else if(elec_jrnl_ptr == (byte *)FLS_SCT08_ADDR)
		elec_jrnl_ptr = (byte *)FLS_SCT07_ADDR;

	else
		;// Do nothing

	return (elec_jrnl_ptr);
}

/* Get the next journal head pointer address */
/* length: 以elec_jrnl_ptr为头指针的电子日志的长度. 
*/
byte	*Get_Next_Head(byte *elec_jrnl_ptr, byte length)
{
	byte	ID;
	byte	*sct_start_addr;
	dword	tmp_len;
	ELECJRNLHEADDEF	*elec_head_ptr;

	if(length == 0)
		return (elec_jrnl_ptr);
	sct_start_addr = (byte *)(FLS_BASE_ADDR + ((dword)elec_jrnl_ptr & 0xF0000));			/* Get the start addres */
	elec_jrnl_ptr += (dword)length*sizeof(TRANSBUFFDEF);
	tmp_len = (dword)elec_jrnl_ptr - (dword)sct_start_addr;
	if(tmp_len >= EACH_SCT_SIZE)		/* 正好相等, 表明正好是到了结尾处.(不会有大于这种情况) */
	{
		sct_start_addr = Get_Next_Logic_Sector(sct_start_addr);
		elec_jrnl_ptr = &sct_start_addr[LOG_START_POSI];
	}
	else
	{
		elec_head_ptr = (ELECJRNLHEADDEF *)elec_jrnl_ptr;
		ID = (elec_head_ptr->ID)&0x1F;
		if((ID == TS_SALE_JRNL) || (ID == TS_DC_JRNL) || (ID == TS_RM_JRNL))		/* The next journal is not void */
		{
			length = elec_head_ptr->length;
			tmp_len += (dword)length*sizeof(TRANSBUFFDEF);
			if(tmp_len > EACH_SCT_SIZE)/* 大于, 表明这个记录无用, 需定位到下一个头去 */
			{
				sct_start_addr = Get_Next_Logic_Sector(sct_start_addr);
				elec_jrnl_ptr = &sct_start_addr[LOG_START_POSI];
			}
		}
	}
	return (elec_jrnl_ptr);
}

/* Get the next free journal head pointer address */
byte	*Get_Next_Free_Head(byte *elec_jrnl_ptr, byte length)
{
//	byte	*sct_start_addr;
//
//	sct_start_addr = (byte *)(FLS_BASE_ADDR + ((dword)elec_jrnl_ptr & 0xF0000));			/* Get the start addres */
//	elec_jrnl_ptr += (dword)length*sizeof(TRANSBUFFDEF);
//	if(((dword)elec_jrnl_ptr - (dword)sct_start_addr) >= EACH_SCT_SIZE)		/* More than a sector size, 在目前的程序中, 只会是一个等于号 */
//	{
//		sct_start_addr = Get_Next_Logic_Sector(sct_start_addr);
//		elec_jrnl_ptr = &sct_start_addr[LOG_START_POSI];
//	}
//	return (elec_jrnl_ptr);
	// -->>	注: 可以使用上面一段程序, 但也可以使用如下语句: 
	return (Get_Next_Head(elec_jrnl_ptr, length));
}

/* Get the next journal record address */
/* Note:
		This fuction used in the PC communication.
*/
byte	*Get_Next_Record(byte *elec_jrnl_ptr)
{
//	byte	ID;
//	byte	*sct_start_addr;
//	dword	tmp_len;
//	ELECJRNLHEADDEF	*elec_head_ptr;
//
//	sct_start_addr = (byte *)(FLS_BASE_ADDR + ((dword)elec_jrnl_ptr & 0xF0000));			/* Get the start addres */
//	elec_jrnl_ptr += /*(dword)1**/sizeof(TRANSBUFFDEF);
//	tmp_len = (dword)elec_jrnl_ptr - (dword)sct_start_addr;
//	if(tmp_len >= EACH_SCT_SIZE)		/* 正好相等, 表明正好是到了结尾处.(不会有大于这种情况) */
//	{
//		sct_start_addr = Get_Next_Logic_Sector(sct_start_addr);
//		elec_jrnl_ptr = &sct_start_addr[LOG_START_POSI];
//	}
//	else
//	{
//		elec_head_ptr = (ELECJRNLHEADDEF *)elec_jrnl_ptr;
//		ID = (elec_head_ptr->ID)&0x1F;
//		if((ID == TS_SALE_JRNL) || (ID == TS_DC_JRNL) || (ID == TS_RM_JRNL))		/* The next journal is not void */
//		{
//			length = elec_head_ptr->length;
//			tmp_len += (dword)length*sizeof(TRANSBUFFDEF);
//			if(tmp_len > EACH_SCT_SIZE)/* 大于, 表明这个记录无用, 需定位到下一个头去 */
//			{
//				sct_start_addr = Get_Next_Logic_Sector(sct_start_addr);
//				elec_jrnl_ptr = &sct_start_addr[LOG_START_POSI];
//			}
//		}
//	}
//	return (elec_jrnl_ptr);
	// -->>	注: 可以使用上面一段程序, 但也可以使用如下语句: 
	return (Get_Next_Head(elec_jrnl_ptr, 1));
}

/* Get the exact record address */
/* Note:
		This fuction used in the PC communication.
*/
byte	*Get_Record(byte *elec_jrnl_ptr, word idx)
{
	while(-- idx)
	{
		elec_jrnl_ptr = Get_Next_Record(elec_jrnl_ptr);
	}
	return (elec_jrnl_ptr);
}

/* Locate the sale journal */
void	Sale_Jrnl_Loc(byte *sale_jrnl_addr)
{
	byte	i;
	byte	length;
	byte	*head_ptr;
	byte	*last_head_ptr;
	byte	*rear_ptr;
	word	curr_len;				/* The current length */
	word	elec_jrnl_first;
	word	elec_jrnl_last;

	head_ptr = rear_ptr = &sale_jrnl_addr[LOG_START_POSI];
	last_head_ptr = head_ptr;
	curr_len = 0;
	elec_jrnl_first = elec_jrnl_last = 0;
	while(TRUE)
	{
		if((((ELECJRNLHEADDEF *)head_ptr)->ID&0x1F) != TS_SALE_JRNL)		/* The record is void */
		{
			sale_jrnl = (TRANSBUFFDEF *)rear_ptr;
			sale_jrnl_first_ptr = (byte *)sale_jrnl;
			sale_jrnl_last_ptr = last_head_ptr;
			sale_jrnl_last = elec_jrnl_last - elec_jrnl_first;
			sale_jrnl_len = elec_jrnl_last - elec_jrnl_first;	/* = sale_jrnl_last */
			sale_jrnl_first = 0;
			break;
		}
		else	/* The record is not void */
		{
			length = (((ELECJRNLHEADDEF *)head_ptr)->length);
			last_head_ptr = head_ptr;
			head_ptr = Get_Next_Head(head_ptr, length);			/* Get the next journal head */
			elec_jrnl_last += length;
			curr_len += length;
			while(curr_len > Max_Sale_Jrnl_No)	/* The length is larger than the max length */
			{
				length = (((ELECJRNLHEADDEF *)rear_ptr)->length);
				rear_ptr = Get_Next_Head(rear_ptr, length);		/* Get the next journal rear */
				elec_jrnl_first += length;
				curr_len -= length;
			}
		}
	}
}

/* Locate the discount journal */
void	Dc_Jrnl_Loc(byte *dc_jrnl_addr)
{
	byte	i;
	byte	length;
	byte	*head_ptr;
	byte	*last_head_ptr;
	byte	*rear_ptr;
	word	curr_len;				/* The current length */
	word	elec_jrnl_first;
	word	elec_jrnl_last;

	head_ptr = rear_ptr = &dc_jrnl_addr[LOG_START_POSI];
	last_head_ptr = head_ptr;
	curr_len = 0;
	elec_jrnl_first = elec_jrnl_last = 0;
	while(TRUE)
	{
		if((((ELECJRNLHEADDEF *)head_ptr)->ID&0x1F) != TS_DC_JRNL)		/* The record is void */
		{
			dc_jrnl = (TRANSBUFFDEF *)rear_ptr;
			dc_jrnl_first_ptr = (byte *)dc_jrnl;
			dc_jrnl_last_ptr = last_head_ptr;
			dc_jrnl_last = elec_jrnl_last - elec_jrnl_first;
			dc_jrnl_len = elec_jrnl_last - elec_jrnl_first;	/* = dc_jrnl_last */
			dc_jrnl_first = 0;
			break;
		}
		else	/* The record is not void */
		{
			length = (((ELECJRNLHEADDEF *)head_ptr)->length);
			last_head_ptr = head_ptr;
			head_ptr = Get_Next_Head(head_ptr, length);			/* Get the next journal head */
			elec_jrnl_last += length;
			curr_len += length;
			while(curr_len > Max_Dc_Jrnl_No)	/* The length is larger than the max length */
			{
				length = (((ELECJRNLHEADDEF *)rear_ptr)->length);
				rear_ptr = Get_Next_Head(rear_ptr, length);		/* Get the next journal rear */
				elec_jrnl_first += length;
				curr_len -= length;
			}
		}
	}
}

/* Locate the R.M. journal */
void	Rm_Jrnl_Loc(byte *rm_jrnl_addr)
{
	byte	i;
	byte	length;
	byte	*head_ptr;
	byte	*last_head_ptr;
	byte	*rear_ptr;
	word	curr_len;				/* The current length */
	word	elec_jrnl_first;
	word	elec_jrnl_last;

	head_ptr = rear_ptr = &rm_jrnl_addr[LOG_START_POSI];
	last_head_ptr = head_ptr;
	curr_len = 0;
	elec_jrnl_first = elec_jrnl_last = 0;
	while(TRUE)
	{
		if((((ELECJRNLHEADDEF *)head_ptr)->ID&0x1F) != TS_RM_JRNL)		/* The record is void */
		{
			rm_jrnl = (TRANSBUFFDEF *)rear_ptr;
			rm_jrnl_first_ptr = (byte *)rm_jrnl;
			rm_jrnl_last_ptr = last_head_ptr;
			rm_jrnl_last = elec_jrnl_last - elec_jrnl_first;
			rm_jrnl_len = elec_jrnl_last - elec_jrnl_first;	/* = rm_jrnl_last */
			rm_jrnl_first = 0;
			break;
		}
		else	/* The record is not void */
		{
			length = (((ELECJRNLHEADDEF *)head_ptr)->length);
			last_head_ptr = head_ptr;
			head_ptr = Get_Next_Head(head_ptr, length);			/* Get the next journal head */
			elec_jrnl_last += length;
			curr_len += length;
			while(curr_len > Max_Rm_Jrnl_No)	/* The length is larger than the max length */
			{
				length = (((ELECJRNLHEADDEF *)rear_ptr)->length);
				rear_ptr = Get_Next_Head(rear_ptr, length);		/* Get the next journal rear */
				elec_jrnl_first += length;
				curr_len -= length;
			}
		}
	}
}

/* Judge the rear pointer is in this factor or not */
BOOL	elec_rear_judge(byte *elec_jrnl_ptr)
{
	if(elec_jrnl_ptr[LOG_ATV_POSI] == 0x55)
		return (NG);
	if(elec_jrnl_ptr[JRNL_ERS_POSI] == 0x55)		/* Has erase the position */
	{
		if((elec_jrnl_ptr[REAR_PTR2_POSI] == 0x55) && (elec_jrnl_ptr[REAR_PTR_POSI] == 0xFF))
			return (OK);
		else
			return (NG);
	}
	else	// JRNL_ERS_POSI[JRNL_ERS_POSI] == 0xFF
	{
		if(elec_jrnl_ptr[REAR_PTR_POSI] == 0x55)
			return (NG);
		else
			return (OK);
	}
}

/* Recovery the log from the flash for the memory is blocked */
void	Log_Recovery(void)
{
	byte	i;
	byte	*sale_jrnl_addr;
	byte	*dc_jrnl_addr;
	byte	*rm_jrnl_addr;

	/*--------------------------------------*
			Recovery the sale journal
	 *--------------------------------------*/
	sale_jrnl_addr = (byte *)SALE_JRNL_START;
	if((sale_jrnl_addr[STORE_LOG_POSI]) == 0xFF)					/* Has not ever store the sale journal */
	{
		sale_jrnl = (TRANSBUFFDEF *)(&sale_jrnl_addr[LOG_START_POSI]);
		sale_jrnl_first_ptr = sale_jrnl_last_ptr = (byte *)sale_jrnl;
		sale_jrnl_first = sale_jrnl_last = 0;
		sale_jrnl_len = 0;
	}
	else
	{
		for(i = 0; i < 3; i ++)			/* Locate the rear position */
		{
			if(elec_rear_judge(sale_jrnl_addr) == OK)				/* Judge the rear pointer is in this sector */
			{
				break;
			}
			else		/* The rear pointer is not in this sector */
			{
				sale_jrnl_addr = Get_Next_Logic_Sector(sale_jrnl_addr);
			}
		}
		if(i != 3)		/* Note: When the i == 3, indicate the FLASH is wrong, will not occur this case */
			Sale_Jrnl_Loc(sale_jrnl_addr);
	}
	/*--------------------------------------*/

	/*--------------------------------------*
			Recovery the discount journal
	 *--------------------------------------*/
	dc_jrnl_addr = (byte *)DC_JRNL_START;
	if((dc_jrnl_addr[STORE_LOG_POSI]) == 0xFF)					/* Has not ever store the discount journal */
	{
		dc_jrnl = (TRANSBUFFDEF *)(&dc_jrnl_addr[LOG_START_POSI]);
		dc_jrnl_first_ptr = dc_jrnl_last_ptr = (byte *)dc_jrnl;
		dc_jrnl_first = dc_jrnl_last = 0;
		dc_jrnl_len = 0;
	}
	else
	{
		for(i = 0; i < 3; i ++)			/* Locate the rear position */
		{
			if(elec_rear_judge(dc_jrnl_addr) == OK)				/* Judge the rear pointer is in this sector */
			{
				break;
			}
			else		/* The rear pointer is not in this sector */
			{
				dc_jrnl_addr = Get_Next_Logic_Sector(dc_jrnl_addr);
			}
		}
		if(i != 3)		/* Note: When the i == 3, indicate the FLASH is wrong, will not occur this case */
			Dc_Jrnl_Loc(dc_jrnl_addr);
	}
	/*--------------------------------------*/

	/*--------------------------------------*
			Recovery the R.M. journal
	 *--------------------------------------*/
	rm_jrnl_addr = (byte *)RM_JRNL_START;
	if((rm_jrnl_addr[STORE_LOG_POSI]) == 0xFF)					/* Has not ever store the R.M. journal */
	{
		rm_jrnl = (TRANSBUFFDEF *)(&rm_jrnl_addr[LOG_START_POSI]);
		rm_jrnl_first_ptr = rm_jrnl_last_ptr = (byte *)rm_jrnl;
		rm_jrnl_first = rm_jrnl_last = 0;
		rm_jrnl_len = 0;
	}
	else
	{
		for(i = 0; i < 3; i ++)			/* Locate the rear position */
		{
			if(elec_rear_judge(rm_jrnl_addr) == OK)				/* Judge the rear pointer is in this sector */
			{

⌨️ 快捷键说明

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