刚做一个项目,需要使用多种传感器,每种传感器各有4到6个不同配置参数,而且要求这些参数可灵活配置。因此采取了一种方案,将配置参数写在一个固定名称的文件内,设备初始化时从配置文件中读取参数。参数需要修改时,在配置文件中修改需要改动的参数,然后导入设备中(网络下载,TFTP下载等)。
工作不难,但是实现起来比较繁杂。现在介绍实现过程中,使用的几个函数,以及他们起到的作用。
1从指定文件中读取固定字段的后一段配置参数:
(比入从配置文件读取上位机的IP地址及端口号,配置文件中写有IPPort=192.168.1.2:8080)
/******************************************************************************
* Description : ram_fseek
* Arguments : profile==> 配置文件的名称 KeyName=>查找字段
* Returns : KeyVal==>输出的字段
* Caller : APP layer.
* Notes : none.
*******************************************************************************/
int GetProfileString_m(char *profile,char *KeyName, char *KeyVal)
{
char buf_i[KEYVALLEN];
FILE *fp;
char *tp;
int i;
if( (fp=fopen( profile,"r" ))==NULL )
{
printf( "openfile [%s] error [%s]\n",profile,strerror(errno) );
return(-1);
}
fseek( fp, 0, SEEK_SET );
while( !feof(fp) && fgets( buf_i, KEYVALLEN, fp )!=NULL )
{
if(buf_i[0] == '#')
{
continue;
}
tp = strstr( buf_i,KeyName);
if(tp != NULL)
{
tp = strstr(tp, "=");
if(tp != NULL)
{
for(i = strlen(buf_i); i >= 0; i--)
{
if(*(tp + i) == '+')
{
*(tp + i) = 0;
}
}
strcpy(KeyVal, tp + 1);
return 0;
}
}
}
fclose( fp );
return -1;
}
2向指定文件中的固定字段的后写入一段配置参数:
/******************************************************************************
* Description : ram_fseek
* Arguments :profile==> 配置文件的名称 KeyName=>查找字段 KeyVal==>输出的字段
* Returns :
* Caller : APP layer.
* Notes : none.
*******************************************************************************/
int PutProfileString_m(char *profile,char *KeyName, char *KeyVal)
{
char buf_i[KEYVALLEN];
FILE *fp;
char *tp;
int ct,len; ;
if( (fp=fopen( profile,"r+" ))==NULL )
{
printf( "openfile [%s] error [%s]\n",profile,strerror(errno) );
return(-1);
}
fseek( fp, 0, SEEK_SET );
while( !feof(fp) && fgets( buf_i, KEYVALLEN, fp )!=NULL )
{
tp = strstr( buf_i, KeyName);
if(tp != NULL)
{
len = strlen(buf_i);
fseek(fp, (len)* (-1), SEEK_CUR);/*找到查找字段的位置*/
bzero(buf_i, sizeof(KEYVALLEN));
strcpy(buf_i,KeyName);
strcat(buf_i,"=");
strcat(buf_i,KeyVal);
for(ct = strlen(buf_i); ct < len - 1; ct++ )
{
buf_i[ct] = '+';/*填充加号*/
}
buf_i[len - 1] = '\n';/*加上换行符*/
fputs(buf_i, fp);/*写入*/
break;
}
}
fclose( fp );
return 0;
}
3读取传感器的配置参数
Prsc:读取到的字符串
Pgp:存储传感器的参数结构体
int Parse_ComportConfigStr(ComportStruct *pgp, char *psrc)
{
char *p1,*p2,*ptemp,*p4,tempbuf[10];
ptemp = psrc;
p1=strstr(ptemp,"(");
p2=strstr(ptemp,")");
if(p1 != NULL && p2 != NULL)
{
sscanf(p1+1, "%d,%d,%d,%d", &(pgp->comport), &(pgp->addrs), &(pgp->Ax), &(pgp->B));
printf("comport=%d,addrs=%d,A=%f,B=%f\n",
pgp->comport,pgp->addrs
, pgp->Ax,pgp->B);
}
}
4检查参数的个数是否正确(参数格式为(%d,%d,%d,%d)或(%d,%d,%f,%f,%f,%f))
table:读取到的字符串
num:参数个数
正确返回0,错误返回-1
int CheckParameter(char *table, int num)
{
int rec=0;
int temp = num;
char *p=table;
while(num--)
{
if ((p = strstr(p, ",")) != NULL)
{
rec++;
p = p + 1;
}
else
{
break;
}
}
if(temp == rec+1)
{
return 0;
}
else
{
return -1;
}
}
5某种传感器,使用的个数较多,每个传感器的参数各不相同,配置文件中需要写入传感器个数,每一个传感器的配置参数。考虑到方便及方便理解,一个传感器的参数作为一组来处理。配置文件中的参数形式(num,(1,2,3,4),(1,2,3,4),(1,2,3,4),....),即num,(%d,%d,%d,%d),.....
读取配置信息时,需要读取这种传感器的总数,以及每个传感器的参数。
int Parse_configstr(SensorGrpStruct *pgp, char *psrc)
{
char *p1,*p2,*ptemp,*p4,tempbuf[10];
int i, j;
j = (psrc[0] - '0') < MAX_SENSOR_GRP_NUMS ? (psrc[0] - '0') : MAX_SENSOR_GRP_NUMS;
pgp->groupsnum = j;
printf("groupsnum = %d ", j);
ptemp = psrc;
i = 0;
do
{
p1=strstr(ptemp,"(");
p2=strstr(ptemp,")");
if(p1 != NULL && p2 != NULL)
{
sscanf(p1+1, "%d,%d,%d,%d",
&(pgp->sensor[i].comport),
&(pgp->sensor[i].addrs),
&(pgp->sensor[i].Ax),
&(pgp->sensor[i].B));
printf("sensor[%d],port=%d,addrs=%d,A=%d,B=%d\n",
i,
pgp->sensor[i].comport,
pgp->sensor[i].addrs,
pgp->sensor[i].Ax,
pgp->sensor[i].B
);
}
ptemp = p2 + 1;
i++;
}
while(i < j);
}