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

📄 ftankvolume.c

📁 这是一个潜入式开发的c语言代码
💻 C
字号:
#include "ftankvolume.h"

VolumeCfg CONFIGUATIONS;						// configuations
BYTE TANKVOLUME_BUFFER[FVOL_TANKBUFFER_SIZE];	// tank volume-table buffer. 50k


/* get configurations */
Boolean fvol_getConfig(CHAR* filename, VolumeCfg* cfg)
{
	REGINT i,size,offset;

	DBG_MSG("get configuration..\n");
	// open & get the number of tanks
	//if ((cfg->fd = open (filename, O_RDONLY|O_BINARY)) < 0)
	if ((cfg->fd = open (filename, O_RDONLY)) < 0)
	{
		DBG_MSG2("open file '%s' failed\n", filename);
		return False;
	}

	if(f_SeekRead(cfg->fd, &cfg->u8TankNum, 0, 1) != 1)
		return False;
	if(cfg->u8TankNum > MAX_TANK_NUM)
	{
		DBG_MSG("tank number overrange error.\n");
		return False;
	}

	// parase tanks
	offset = 1;
	for(i=0; i<cfg->u8TankNum; i++)
	{
		size = sizeof(cfg->_cfgFiles[i]);
		if(f_SeekRead(cfg->fd, cfg->_cfgFiles[i], offset+i*size, size) != size)
			return False;

		cfg->cfgFiles[i] = cfg->_cfgFiles[i];
	}

	close(cfg->fd);
	DBG_MSG("configed successfully\n");
	return True;
}

Boolean fvol_init(CHAR* cfgFileName)
{
	Boolean re = False;
	VolumeCfg* cnf = &CONFIGUATIONS;
	DBG_MSG("init..\n");

	// get configuations
	if( fvol_getConfig(cfgFileName, cnf) == False)
	{
		close(cnf->fd);
		return False;
	}

	DBG_MSG("init finished\n");
	return True;
}

Boolean fvol_bufferVolumeTable(VolumeTable* table, REGINT fd, INT32 offset, BYTE* buffer, INT32* usedsize)
{
	INT32 bufsize;
	UINT16 itemNum;
	VolumeTableType type;

	*usedsize = 0;
	type = table->Type;

	if(f_SeekRead(fd, &itemNum, offset, 2) != 2)
		return False;

	switch(type)
	{
		case Index:
			bufsize = 8 * itemNum;
			break;
		case Ratable0:
			bufsize = 80 * itemNum;
			break;
		default:
			return False;
	}

	if(f_SeekRead(fd, buffer, offset, bufsize) != bufsize)
		return False;

	table->u16ItemNum = itemNum;
	*usedsize = bufsize;
	return True;
}

Boolean fvol_bufferTankdata(TankVolCfg* tank, INT32 tankIndex)
{
	REGINT size,offset,bufcount;
	UINT32 usize;
	struct stat sb;

	DBG_MSG2("tank index: %d\n", tankIndex);
	DBG_MSG("init tank data..\n");


	// --- open ---
	//if ((tank->fd = open (CONFIGUATIONS.cfgFiles[tankIndex], O_RDONLY|O_BINARY)) < 0)
	if ((tank->fd = open (CONFIGUATIONS.cfgFiles[tankIndex], O_RDONLY)) < 0)
	{
		DBG_MSG2("open configuration file '%s' failed\n", CONFIGUATIONS.cfgFiles[tankIndex]);
		return False;
	}
	fstat(tank->fd, &sb);
	if(sb.st_size > FVOL_TANKBUFFER_SIZE)
	{
		DBG_MSG3("tank cfgfile %s is too big, %d bytes limit\n", CONFIGUATIONS.cfgFiles[tankIndex], FVOL_TANKBUFFER_SIZE);
		return False;
	}

	// --- get tank info---
	DBG_MSG("tank coefficients.. \n");
	offset = 0;
	size = sizeof(tank->Name);				
	if(f_SeekRead(tank->fd, tank->Name, offset, size) != size)
	{	
		return False;
	}

	offset = 20;
	if(f_SeekRead(tank->fd, &tank->DM_TABLE.n32Offset, offset, 4) != 4)
		return False;
	if(f_SeekRead(tank->fd, &tank->MM_TABLE.n32Offset, offset+4, 4) != 4)
		return False;
	if(f_SeekRead(tank->fd, &tank->AMEND_TABLE.n32Offset, offset+8, 4) != 4)
		return False;
	if(f_SeekRead(tank->fd, &tank->FUND_TABLE.n32Offset,offset+12, 4) != 4)
		return False;


	// --- buffer volume table ---
	DBG_MSG("volume table.. \n");
	bufcount = 0;

	// DM table
	tank->DM_TABLE.Type = Index;
	tank->DM_TABLE.u16ItemNum = 0;
	if(tank->DM_TABLE.n32Offset > 0)
	{
		if(fvol_bufferVolumeTable(&tank->DM_TABLE, tank->fd, tank->DM_TABLE.n32Offset, TANKVOLUME_BUFFER + bufcount, &usize) == False)
			return False;
		tank->DM_TABLE.n32Offset = bufcount;
		bufcount += usize;
	}

	// MM table
	tank->MM_TABLE.Type = Ratable0;
	tank->MM_TABLE.u16ItemNum = 0;
	if(tank->MM_TABLE.n32Offset > 0)
	{
		if(fvol_bufferVolumeTable(&tank->MM_TABLE, tank->fd, tank->MM_TABLE.n32Offset, TANKVOLUME_BUFFER + bufcount, &usize) == False)
			return False;
		tank->MM_TABLE.n32Offset = bufcount;
		bufcount += usize;
	}

	// Amend table
	tank->AMEND_TABLE.Type = Index;
	tank->AMEND_TABLE.u16ItemNum = 0;
	if(tank->AMEND_TABLE.n32Offset > 0)
	{
		if(fvol_bufferVolumeTable(&tank->AMEND_TABLE, tank->fd, tank->AMEND_TABLE.n32Offset, TANKVOLUME_BUFFER + bufcount, &usize) == False)
			return False;
		tank->AMEND_TABLE.n32Offset = bufcount;
		bufcount += usize;
	}

	// Fund table
	tank->FUND_TABLE.Type = Index;
	tank->FUND_TABLE.u16ItemNum = 0;
	if(tank->FUND_TABLE.n32Offset > 0)
	{
		if(fvol_bufferVolumeTable(&tank->FUND_TABLE, tank->fd, tank->FUND_TABLE.n32Offset, TANKVOLUME_BUFFER + bufcount, &usize) == False)
			return False;
		tank->FUND_TABLE.n32Offset = bufcount;
		bufcount += usize;
	}

	close(tank->fd);
	DBG_MSG("tank data init ok\n");
	return True;
}

INT32 fvol_calVolume(TankVolCfg* tank, TankCoefficient* pTankData)
{
	INT32 liquidLevel;
	INT32 dmvalue,mmvalue,cval,result;
	MatchValue dmdetail, mmdetail;

	liquidLevel = pTankData->volParams.n32LiquidLevel.value;

	// get m-dm volume
	cval = liquidLevel;
	if( (dmvalue = fvol_getValue(&tank->DM_TABLE, cval, liquidLevel, False, &dmdetail)) < 0)
	{
		print("calculate dm value failed\n");
		return -1;
	}
	
	if(dmdetail.isExactValue == True || (liquidLevel - dmdetail.n32RangeA) > 99)
	{
		mmvalue = 0;
	}
	else
	{
		// get m-dm volume
		cval = dmdetail.n32RangeA;
		if( (dmvalue = fvol_getValue(&tank->DM_TABLE, cval, liquidLevel, True, &mmdetail)) < 0)
		{
			print("calculate dm value failed\n");
			return -1;
		}

		// get cm-mm volume
		cval = liquidLevel - dmdetail.n32RangeA;
		if( (mmvalue = fvol_getValue(&tank->MM_TABLE, cval, liquidLevel, True, &mmdetail)) < 0)
		{
			print("calculate mm value failed\n");
			return -1;
		}
	}

	// get base volume
	// get revisory volume
	// calculate with tank coefficients
	result = dmvalue + mmvalue;
	return result;
}

INT32 fvol_getVolume(REGINT tankIndex, TankCoefficient* pTankData)
{
	TankVolCfg tank;

	if(tankIndex <0 || (tankIndex + 1)>MAX_TANK_NUM)
		return -1;

	if( !fvol_bufferTankdata(&tank, tankIndex) )
	{
		close(tank.fd);
		return -1;
	}

	return fvol_calVolume(&tank, pTankData);
}

INT32 fvol_matchIndexVolume(VolumeTable* table, INT32 matchvalue, Boolean matchExactly, MatchValue* detail)
{
	REGINT index,i,j;
	DOUBLE dtempval;
	REGINT theorSearchTimes;
	REGINT countSearchTimes;
	IndexItem tempIndexItem;
	IndexItem tempIndexItem2;
	INT32 result = -1;

	if(table->u16ItemNum <= 0)
		return -1;
	else if(matchvalue == 0)
		return 0;
	else
	{
		index = 0;
		i=0; j = table->u16ItemNum - 1;
		countSearchTimes = 0;
		theorSearchTimes = table->u16ItemNum/2 + 1;

		while(index < table->u16ItemNum)
		{
			index = (i+j)/2;
			if(fvol_GetIndexItem(table, &tempIndexItem, index) )
			{
				if(matchvalue == tempIndexItem.n32Index)
				{
					result = tempIndexItem.n32Value;
					detail->isExactValue = True;
					break;
				}
				else if(i+1 == j)
				{
					if(fvol_GetIndexItem(table, &tempIndexItem, i) && fvol_GetIndexItem(table, &tempIndexItem2, j))
					{
						detail->isExactValue = True;

						if(matchvalue == tempIndexItem.n32Index)
							result = tempIndexItem.n32Value;
						else if(matchvalue == tempIndexItem2.n32Index)
							result = tempIndexItem2.n32Value;
						else if(matchExactly == True)
						{	
							// do nothing 
						}
						else if(matchvalue>tempIndexItem.n32Index && matchvalue<tempIndexItem2.n32Index)
						{
							detail->isExactValue = False;
							detail->n32RangeA = tempIndexItem.n32Index;
							detail->n32RangeB = tempIndexItem2.n32Index;

							dtempval = (DOUBLE)(tempIndexItem2.n32Index-tempIndexItem.n32Index);
							if(dtempval == 0)
								result = (tempIndexItem.n32Value + tempIndexItem2.n32Value)/2;
							else
							{
								dtempval = (DOUBLE)(tempIndexItem2.n32Value-tempIndexItem.n32Value) / dtempval;
								result = tempIndexItem.n32Value + dtempval * (matchvalue - tempIndexItem.n32Index);
							}
						}
					}
					
					break;
				}
				else if(i == j)
					break;
				else if(matchvalue < tempIndexItem.n32Index)
					j = index;
				else
					i = index;
			}
			else break;


			if(++countSearchTimes > theorSearchTimes)
				break;
		}
	}

	if(result == -1)
	{
		print("can't match index value:%d\n", matchvalue);
	}
	return result;
}

INT32 fvol_matchRatable0Volume(VolumeTable* table, INT32 matchvalue, INT32 liquidLevel)
{
	REGINT index,i,j;
	REGINT theorSearchTimes,countSearchTimes;
	RatableItem tempRatableItem;
	INT32 result;

	result = -1;
	ASSERT(matchvalue > 99);
	

	if(table->u16ItemNum <= 0)
		return -1;
	else if(matchvalue == 0)
		return 0;
	else
	{
		index = 0;
		i=0; j = table->u16ItemNum-1;
		countSearchTimes = 0;
		theorSearchTimes = table->u16ItemNum/2 + 1;

		while(index < table->u16ItemNum)
		{
			index = (i+j)/2;
			if(fvol_GetRatable0Item(table, &tempRatableItem, index) )
			{
				if(liquidLevel >= tempRatableItem.n32LiquidLevel_Min && liquidLevel<tempRatableItem.n32LiquidLevel_Max)
				{
					result = 0;
					if(matchvalue/10 > 0)
						result += tempRatableItem.unitage_cm[matchvalue/10-1];
					if(matchvalue%10 > 0)
						result += tempRatableItem.unitage_mm[matchvalue%10-1];
					break;
				}
				else if(i == j)
					break;
				else if(liquidLevel < tempRatableItem.n32LiquidLevel_Min)
					j = index - 1;
				else
					i = index + 1;
			}
			else break;

			if(++countSearchTimes > theorSearchTimes)
				break;
		}
	}

	if(result == -1)
	{
		print("can't match ratable value at liquidlevel %d\n", liquidLevel);
	}
	return result;
}

INT32 fvol_getValue(VolumeTable* table, INT32 matchvalue, INT32 liquidLevel, Boolean matchExactly, MatchValue* detail)
{
	switch(table->Type)
	{
		case Index:
			return fvol_matchIndexVolume(table, matchvalue, matchExactly, detail);
		case Ratable0:
			return fvol_matchRatable0Volume(table, matchvalue, liquidLevel);
	}

	return -1;
}

Boolean fvol_GetIndexItem(VolumeTable* table, IndexItem* item, INT32 index)
{
	REGINT offset;
	ASSERT(index < 0 || index >= table->u16ItemNum);

	offset = (REGINT)TANKVOLUME_BUFFER + table->n32Offset + 2;
	offset += index*8;

	memcpy(&item->n32Index, offset, 4);
	memcpy(&item->n32Value, offset + 4, 4);

	return True;
}

Boolean fvol_GetRatable0Item(VolumeTable* table, RatableItem* item, INT32 index)
{
	REGINT offset,size;
	ASSERT(index < 0 || index >= table->u16ItemNum);

	offset = TANKVOLUME_BUFFER + table->n32Offset + 2;
	offset += index*80;
	
	memcpy(&item->n32LiquidLevel_Min, offset, (size=4) );
	offset += size;
	memcpy(&item->n32LiquidLevel_Max, offset, (size=4));
	offset += size;
	memcpy(&item->unitage_cm, offset, (size=36));
	offset += size;
	memcpy(&item->unitage_mm, offset, (size=36));

	return True;
}

⌨️ 快捷键说明

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