分散控制系统中SRAM应用

2015-07-21 09:45盛华刘书刚葛树俊
物联网技术 2015年7期

盛华+刘书刚+葛树俊

摘 要:当前DCS广泛应用于发电厂,但由于实时数据掉电容易丢失,缺乏带掉电保护装置,从而影响整个现场控制站的稳定性和实时性,因此,在现场控制站的硬件中加入SRAM,能够保存I/O数据和强制信息,并在设备重启之后读取保存的信息。

关键词:现场控制站;DCS;SRAM;保存信息

中图分类号:TM72 文献标识码:B 文章编号:2095-1302(2015)07-00-03

0 引 言

目前DCS广泛应用于电厂。它和通用的DCS系统一样,按电厂运行逻辑根据各种模拟数据量,经过电厂运行的逻辑实现对各种执行部件的控制。不仅要实现准确采集各种数据和正确发出控制指令等基本功能,最重要的是能对各种数据进行分析和判断,并执行相应操作。DCS在火力发电厂中的广泛采用,大大提高了机组运行的可靠性和经济性。

但是,意外情况会导致现场控制站不能正常工作。DPU停止工作时,而实时数据不能获取,现场控制站重启后,实时数据和上位机下发的强制信息都清零。针对这一问题,可对现有分散控制系统DCS进行改进,在其控制板中加入SRAM。这样当现场控制站重启时,读取掉电前的数据和指令既可。

1 SRAM简介

SRAM(Static Random Access Memory),即静态随机存取存储器。它是一种具有静止存取功能的内存,不需要刷新电路即能保存它内部存储的数据。因此,在存储数据方面能防止数据丢失。另外,SRAM具有较高的性能,较低的功耗,主要用于二级高速缓存,利用晶体管来存储数据。对称的电路结构以及SRAM可以一次接收所有的地址位,使得SRAM的访问速度要快于DRAM,DRAM采用的是行地址和列地址复用的结构。现将它的特点归纳如下:

(1)优点:速度快,不必配合内存刷新电路,可提高整体的工作效率。

(2)缺点:集成度低,掉电能保存数据,功耗较大,相同的容量体积较大,而且价格较高,少量用于关键性系统以提高效率。

2 设计原理

昭营主板VDX-6358RD的SRAM是挂载到ISA总线上的,地址总线占据A0~A14,寻址空间为32 K,通过GP3口的高四位寻址A15~A18。这样就可以实现寻址512 K大小的SRAM。ISA总线通过配置GPCS1,配置ISA的空间地址0Xd8000。

3 安全控制器的实现

在安全控制器实现过程中,主要考虑数据结构,以及在SRAM中的存储。安全控制器主要包括两部分数据存储:IO卡件和SAMA组态的数据。存储到SRAM中采用的数据结构分为三部分:帧头、数据、帧尾。如表1所列。

表 1 数据结构

帧头 数据 帧尾

16字节 N字节 4字节

帧头包含类型、保留、模块总数、总数据长度。如表2所列。

表2 帧头组成及各部分长度

类型 保留 模块总数 总数据长度

4字节 4字节 4字节 4字节

数据部分包含四部分:模块类型、模块ID、模块长度、模块数据。在模块类型中,2015代表IO卡件,2014代表SAMA组态。如表3所列。

表 3 数据部分的构成

模块类型 模块ID 模块长度 模块数据

2字节 4字节 2字节 N字节

为了方便后期验证设置:帧尾数据 = 总数据长度|数据类型。

4 SRAM读写操作

需要定义的变量如下:

void *Sram_Data_Buffer; //Sram数据缓冲区

void *Sram_Data_Pointer; //Sram数据指针

short Sram_point_type; //Sram数据类型

unsigned int Sram_buf_len; //Sram数据缓冲区长度

unsigned int sram_data_len; //Sram数据长度

unsigned char sram_cur_page; //Sram当前页

unsigned int sram_page_cur_offset; //Sram当前页的偏移量

4.1 SRAM写操作

为了节省内存空间,又要考虑整体的效率,所以,一般按照页大小来开辟内存空间,而开辟内存空间大小的时候,采用的机制是要比页的大小稍微大点,是遍历完一个模块数据之后才判断当前数据长度是否大于页的大小,如果开辟太小则有可能会溢出。

比如在遍历下一个模块的时候,Sram_buf_len 已经是接近页的大小,但还是小于页的大小,此时在遍历下一个模块的时候,Sram_buf_len已经是大于页的大小了,如果开辟的空间太小,进程就会崩溃。因此在写操作的时候,要时刻注意当前页,及当前页的偏移量。

写数据的流程如下:

(1)判断数据长度是否超过剩余空间的大小。

sram_addr = sram_cur_page*SRAM_PAGE_SIZE +sram_page_cur_offset+buff_len;

page = sram_addr/SRAM_PAGE_SIZE;

offset = sram_addr%SRAM_PAGE_SIZE;

if((page>15)||((page== 15)&&(offset>0)))

{

page = 0;

sram_page_cur_offset = 16;

sram_cur_page = 0;

return 1;

}

当前地址+要写的数据长度是否超过了剩余空间,超过提示错误信息,否则进行下一步。

(2)判断要写的数据是否大于当前页剩余的空间,如果大于当前页剩余的空间,则先写当前页,之后再写剩下的数据。因为涉及到页的操作,所以写完当前页之后,再计算剩余数据需要占用的空间,先写页,再写小于页的数据。

if(buff_len > offset) //判断要写的数据是否大于当前页剩余空间

{

//当前页剩余量

or(j = 0;j

{

pointer = MK_FP(base,sram_page_cur_offset);

*pointer = *((unsigned char *)Sram_Data_Pointer);

Sram_Data_Pointer= (unsigned char *)Sram_Data_Pointer+1;

sram_page_cur_offset=sram_page_cur_offset+1;

}

//指向下一页

sram_page_cur_offset = 0;

sram_cur_page =sram_cur_page+1;

sram_set_page(sram_cur_page);

buff_len = buff_len - offset;

page = buff_len/SRAM_PAGE_SIZE;

offset = buff_len%SRAM_PAGE_SIZE;

//写页

for(i = 0;i

{

for(j = 0;j

{

pointer= MK_FP(base, sram_page_cur_offset);

*pointer = *((unsigned char *)Sram_Data_Pointer);

Sram_Data_Pointer=(unsigned char*)sram_Data_Pointer+1;

sram_page_cur_offset=sram_page_cur_offset+1;

}

sram_page_cur_offset = 0;

sram_cur_page =sram_cur_page+1;

sram_set_page(sram_cur_page);

{

//写剩余的字节

for(j = 0;j

{

pointer = MK_FP(base,sram_page_cur_offset);

*pointer = *((unsigned char *)Sram_Data_Pointer);

Sram_Data_Pointer= (unsigned char *)Sram_Data_Pointer+1;

sram_page_cur_offset=sram_page_cur_offset+1;

}

}

如果要写的数据小于或者等于当前页,则直接写数据。

for(j = 0;j

{

pointer = MK_FP(base,sram_page_cur_offset);

*pointer = *((unsigned char *)Sram_Data_Pointer);

Sram_Data_Pointer=(unsigned char *)Sram_Data_Pointer+1;

sram_page_cur_offset=sram_page_cur_offset+1;

}

4.2 SRAM读操作

(1)根据读取数据大小开辟内存空间。

Sram_Read_Buffer= (char *)malloc(DataLen);//one page size

if(Sram_Read_Buffer == NULL)

{

printf("Ana_Sram:sama Unable to malloc Sram_Data_Buffer\n");

return 1;

}

RecvPointer = (char *)Sram_Read_Buffer;

cur_page = (sram_sama_starter_addr+16)/SRAM_PAGE_SIZE;

cur_offset = (sram_sama_starter_addr+16)%SRAM_PAGE_SIZE;

sram_set_page(cur_page);

(2)如果读取数据小于当前页剩余数据,则直接读取。

for(i = 0;i

{

Sram_read_pointer_char = MK_FP(sram_base, cur_offset);

*(char *)RecvPointer = *Sram_read_pointer_char;

RecvPointer=(char *)RecvPointer+ sizeof(char);

cur_offset =cur_offset+1;

}

(3)如果读取数据大于当前页剩余数据,则读取当前页剩余数据,之后在计算剩余数据占据的空间大小,分页读取。

if(DataLen>offset)

{

//读取当前页剩余数据

for(i = 0;i

{

Sram_read_pointer_char = MK_FP(sram_base, cur_offset);

*(char *)RecvPointer = *Sram_read_pointer_char;

RecvPointer=(char *)RecvPointer+ sizeof(char);

cur_offset =cur_offset+1;

}

//计算剩余数据占用空间

cur_page = cur_page+1;

cur_offset = 0;

sram_set_page(cur_page);

page = (DataLen -offset )/SRAM_PAGE_SIZE;

offset = (DataLen-offset)%SRAM_PAGE_SIZE;

//分页读取数据

for( i = 0;i

{

for(j = 0;j

{

Sram_read_pointer_char = MK_FP(sram_base, cur_offset);

*(char *)RecvPointer = *Sram_read_pointer_char;

RecvPointer=(char *)RecvPointer+ sizeof(char);

cur_offset =cur_offset+1;

}

cur_page = cur_page +1;

cur_offset = 0;

sram_set_page(cur_page);

}

for(i = 0;i

{

Sram_read_pointer_char = MK_FP(sram_base, cur_offset);

*(char *)RecvPointer = *Sram_read_pointer_char;

RecvPointer=(char *)RecvPointer+ sizeof(char);

cur_offset = cur_offset+1;

}

}

5 SRAM读写测试

在QNX MomenticsIDE 6.5环境下,利用C语言编写测试程序,测试如下:

(1)读操作,读取地址458 752,读标志位(0),读取数据为00 00 ff 00 ff ff 00 ff ff ff 00 ff ff ff ff 00。

(2)写操作,向地址458 752写入数据,写标志位(1),写入数据为aa 55 aa 55 aa 55 aa 55 aa55 00 00 00 00 00 00。

(3)断电读取数据,读取地址458 752,读标志位(0),读取数据为aa 55 aa 55 aa 55 aa 55 aa55 00 00 00 00 00 00。

通过测试,可对SRAM进行正常的读写操作,掉电后仍能正确读取数据,达到设计的最终目的。测试结果如图1所示。

图1 SRAM测试

6 结 语

在分散控制系统DCS中加入SRAM,防止现场控制站由于意外情况而停止工作,因而造成数据的丢失。设备重启之后,上次的操作信息会重启读取,各个模块的I/O数据及其SAMA组态信息都将保存在SRAM中,不会因为断电而丢失,减少了操作人员的工作量,有利于工作人员对设备进行维护。

参考文献

[1]姚其爽,张昭勇,张盛兵.嵌入式静态随机存储器的低功耗设计[J].科学技术与工程,2007,7(8):1781-1785.

[2]方海涛.高速低功耗嵌入式SRAM的设计[D].武汉:华中科技大学,2012.

[3]周全.高速低功耗SRAM的设计与实现[D].长沙:国防科学技术大学,2013.

[4]周清军,刘红侠,吴笑峰,等.嵌入式SRAM的优化修复方法及应用[J].计算机辅助设计与图形学学报,2008,20(10):1276-1281.

[5]吴殿红.基于8086的SRAM读写控制仿真实现[J].信息通信,2014(2):65-66.