📄 fls_jrnl.c
字号:
/*
* 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 + -