飞思卡尔KEA128微控制器位带技术的应用解析
2016-11-08李跃华王宜怀
李跃华 王宜怀
1(南通大学计算机科学与技术学院 江苏 南通 226019)2(苏州大学计算机科学与技术学院 江苏 苏州 215006)
飞思卡尔KEA128微控制器位带技术的应用解析
李跃华1,2王宜怀2
1(南通大学计算机科学与技术学院江苏 南通 226019)2(苏州大学计算机科学与技术学院江苏 苏州 215006)
在嵌入式系统开发中,对内存的访问需使用“读-改-写”操作,至少会生成三条机器指令,不适合执行速度要求较高场合,此外还可能导致多任务间共享资源的“互锁”问题。详细解析了KEA128微控制器硬件提供的位带技术对SRAM_U内存位操作的工作机制。实例对比分析和应用结果表明,利用位带技术可以降低代码占用空间,减少程序执行的机器指令周期,适合程序员在高级编程中使用该技术实现对位的快速“原子操作”,提高程序运行速度。
SRAM_U位带区位带别名区原子操作互锁
0 引 言
在嵌入式编程中,通常情况下对RAM的操作,只能进行整字节读取/写入。一般需要进行“读-改-写”操作,即读内存赋给临时变量,然后对临时变量进行修改,最后将临时变量结果写回内存[1]。这样编译后会生成多条指令,执行的指令周期长,代码占用空间也大。在嵌入式应用中经常会出现执行效率要求较高的场景,尤其是对RAM的频繁操作需要提高运行速度。使用普通的读取/写入方法,会产生较多的机器指令代码,降低系统的运行效率。此外,在多任务共享资源的“互锁”解决方案中也需要对位的操作特殊处理,实现对位的快速“原子操作”。KEA128微控制器是飞思卡尔针对汽车市场最新开发的微控制器(MCU),有非常广泛的应用范围。由于芯片的高可靠性,也大量应用于一般的工业控制系统中。KEA128微控制器内部具有位带技术这种位操作机制,从硬件上提供了对位带别名区外设地址空间用“读-改-写”的操作方式来实现位操作[2]。硬件设计采用相对比较复杂的映射机制,一般程序员在编程时不会使用,而在高级编程中使用该技术实现对位的快速操作。本文通过详细解析位带技术要点及其与普通位操作方法的比较,并给出实际应用案例场景,为其他编程人员提供参考。使用这种机制能够降低总线的占用率和CPU执行时间,提高系统的运行速度,降低系统的功耗。本文的研究是在国家自然科学基金资助下开展的,该项目的荧光投影数据采集检测模块,需大量处理内存中的采集数据,对于程序的代码空间和运行时间要求较高。使用普通位操作技术很难达到较好的效果,利用本文位带技术设计的评估系统为基金项目中数据检测模块的研究做了一定的探索。
1 KEA128微控制器位带技术机制概述
KEA128微控制器的SRAM(16 KB)分为两部分:SRAM_L(4 KB)和SRAM_U(12 KB)。硬件机制提供利用“位带别名区”对SRAM_U“位带区”的对应位置1或清0操作[2]。位带别名区的32位字地址的写操作与SRAM_U上的目标位的“读-改-写”操作作用相同,但仅需一个指令周期。利用“位带别名区”的98 304字地址编号实现对12 KB 的SRAM_U的98 304个位的操作,位带别名区地址空间(0x22000000-0x2205FFFF,384 KB,98 304字)对应SRAM_U位带区(0x20000000-0x20002FFFF,12 KB)的12×1024×8=98 304个位。位带别名区只支持简单的置1和清0写操作,目的是方便对位的快速原子操作[3,4]。
“位带别名区”操作实质是一种内存映射关系。硬件将SRAM_U“位带区”的存储单元按“位”映射到对应“位带别名区”的32 位“字”上,“位带别名区”中的一个32位地址,对应“位带区”一个地址中的一个位[2,3]。按“字”访问“位带别名区”的存储单元时,就相当于访问“位带区”对应“位”。对“位带别名区”地址的访问等同于对真实地址的某个位的访问。“位带区”与“位带别名区”的映射关系如图1所示。
图1 “位带区”和“位带别名区”的映射关系
通过位带技术映射存储空间之后,编写程序时可以方便实现位操作。“位带别名区”第0位的值决定写入目标位的值,为1代表向目标位写1;为0代表目标位清0。可以通过向“位带别名区”写0x00000000,表明目标位清0;写0x00000001表明目标位置1。根据KEA128微控制器位带区“位”与位带别名区“字”的对应关系,位带别名区地址的计算方法[6]为:位带别名区地址= 位带别名区基地址+ 位带区字节偏移量×32 + 位偏移量×4。设SRAM_U“位带区”的地址为X,需要置1或清0的位为m(0≤m≤31),可以通过公式计算出“位带别名区”的地址为:0x22000000+(X-0x20000000)×32+m×4。
2 KEA128微控制器位带技术应用机制解析
2.1不同方法操作SRAM_U解析
2.1.1普通方法操作SRAM_U
一般情况下,如何修改内存中的一位?如果要求是改动一位,不能影响其他位。以32位字长为例进行解析,设目标地址为0x20002FF0,改动其第16位为“0”的方法如下[5]:
1) 读一个字:读出0x20002FF0-0x20002FF3中内容到变量temp中:
temp=(*( volatile unsigned long int *)(unsigned long int)0x20002FF0);
2) 改一个位:将temp中的第16位清0:
temp=temp&(0xFFFEFFFF);
3) 写一个字:将temp写回目标地址:
(*(volatile unsigned long int *)(unsigned long int)0x20002FF0)=temp;
这就是通常所说的“读-改-写”操作,即读内存赋给临时变量,然后对临时变量进行修改,最后将临时变量结果写回内存。
2.1.2位带技术操作SRAM_U
如果我们使用KEA128微控制器硬件机制所提供的“位带别名区”将SRAM_U“位带区”地址为0x20002FF0的内存单元第16位变成“0”,仅需一步写操作就可以实现:
(*(volatile unsigned long int *)(unsigned long int)0x2205FE40)=0;
其中“位带别名区”的地址0x2205FE40可以通过公式0x22000000+(0x20002FF0-0x20000000)×32+16×4计算得到。
2.2实例对比分析
为了充分说明位带技术的优势,我们在Kinetis Design Studio 2.0.0编译环境中对上述代码反汇编进行对比。可以发现,使用位带技术比原有“读-改-写”方法的代码空间要小,执行效率更高。通过“位带别名区”的写操作就可以实现对SRAM_U“位带区”中位的操作,将位操作的“读-改-写”过程变为只有“写”的操作,提高了程序的运行效率。
普通方法操作SRAM_U的机器码:
//SARM_U位带区读一个字
temp=(*( volatile unsigned long int *)(unsigned long int)0x20002FF0);
80e:4b36 ldrr3, [pc, #216]; (8e8
810:681b ldrr3, [r3, #0]
812:60fb strr3, [r7, #12]
//改一个位
temp=temp&(0xFFFEFFFF);
814:68fa ldrr2, [r7, #12]
816:4b35 ldrr3, [pc, #212]; (8ec
818:4013 andsr3, r2
81a:60fb strr3, [r7, #12]
//SARM_U位带区写一个字
(*( volatile unsigned long int *)(unsigned long int)0x20002FF0)=temp;
81c:4b32 ldrr3, [pc, #200]; (8e8
81e:68fa ldrr2, [r7, #12]
820:601a strr2, [r3, #0]
位带技术操作SRAM_U的机器码:
//位带别名区写一个字
(*( volatile unsigned long int *)(unsigned long int)0x2205FE40)=0x00000000;
822:4b33 ldrr3, [pc, #204]; (8f0
824:2200 movsr2, #0
826:601a strr2, [r3, #0]
3 利用位带技术编程要点
3.1位带技术使用的RAM区域
SRAM_U作为普通内存区时,一般被用来存储全局变量、临时变量(堆栈空间)等。当SRAM_U用作位带区时,仅需使用其中很小一部分区域用作位带区,其余大部分仍然用作普通内存区。如果地址随意使用,位带区和普通内存区会出现重叠,从而出现使用混乱,发生错误。为此,我们一般在链接文件(.LD)中修改堆栈大小和堆栈SP指针,将堆栈的最高地址向小端移动,根据实际项目需要,留出部分高端地址空间给SRAM_U位带区使用。
3.2使用volatile关键字
在C语言编程设计中使用位带技术时,所访问的存储器单元必须使用关键字volatile 来加以定义[6]。该关键字用于规定C 编译器不允许对其限定的变量进行优化处理,编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值。如果这个变量被别的程序更新了的话,将出现不一致的现象。
4 位带技术应用案例
4.1解决多任务间共享资源的“互锁”问题
在嵌入式系统设计中,多任务间共享资源会出现“互锁”问题,采用普通的“读-改-写”操作可能会出现紊乱情况[7]。
比如,利用内存中一个字节,用作状态标记位。在多个中断服务程序中,根据不同的响应中断设置对应的状态标记位;主程序根据状态标记位去执行不同的程序段,然后清除对应的状态标记位。下面利用两种方法来操作状态标记位,并采用位带技术来解决使用普通方法可能存在的“互锁”问题。
4.1.1使用普通方法
采用普通的“读-改-写”操作需要 3 条指令,导致这中间留有两个能被中断的空当,于是可能会出现状态标记位的紊乱情况。假设当主程序main中状态标记位值为0b00000001,需要清除第0位,正处于“读”-“改”间隔或“改”-“写”间隔的时候发生isr_one中断,中断响应后对需要第1位置1。此时,isr_one中断服务程序中读取到状态标记位值仍然为0b00000001,然后进行修改、写入后变为0b00000011。退出中断isr_one服务例程,返回到mian主程序中,继续执行“读”、“改”操作的后续“写”指令。由于发生中断前已经读取了状态标记位的值为0b00000001,修改后为0b00000000,此时会将0b00000000的值写回状态标记位,isr_one中断服务程序中所做的修改动作就会丢失,达不到程序所设计的效果。同样的紊乱情况可能出现在多任务的执行环境中。其实上述的情况可以看作是多任务的一个特例:主程序mian是一个任务,isr_one是另一个任务,这两个任务并发执行[7]。示例程序说明如下:
主程序Main中:
Flag&=~(1<<0);
//清除标记位第0位
//该语句实际上为3条复合语句;假设Flag变量对应地址为:0x20002FF0
Flag=(*( volatile unsignedchar *)(unsigned long int)0x20002FF0);
//此处可能会被isr_one中断
Flag=temp&(0xFE);
//清除第0位
//此处可能会被isr_one中断
(*(volatile unsignedchar *)(unsigned long int)0x20002FF0)=Flag;
isr_one中断服务程序中:
Flag|=(1<<1);
//标记位第1位置1
//该语句实际上为3条复合语句
Flag=(*( volatile unsignedchar *)(unsigned long int)0x20002FF0);
Flag=temp|(0x02);
//第1位置1
(*(volatile unsignedchar *)(unsigned long int)0x20002FF0)=Flag;
4.1.2使用位带技术方法
利用位带技术的好处是在多任务中,可以实现共享资源在任务间的“互锁”访问。多任务的共享资源必须满足一次只有一个任务访问它,即所谓的“原子操作”。通过使用位带技术,就可以避免上例中的紊乱情况。位带操作把这个“读-改-写”操作变成一个硬件级别支持的原子操作,不能被中断。上述main中对状态标记位第0位的清0操作采用位带技术后,执行完清0操作后才会去相应isr_one中断,执行对应的服务例程完成状态标记位第1位的置1操作,这样就不会出现上述紊乱情况。示例程序说明如下:
主程序Main中:
//计算出SRAM_U:0x20002FF0,第0位,对应的位带别名区地
//址:0x2205FE00
//计算出SRAM_U:0x20002FF0,第1位,对应的位带别名区地
//址:0x2205FE04
//清除标记位第0位
(*(volatile unsigned long int *)(unsigned long int) 0x2205FE00)=0;
isr_one中断服务程序中:
//标记位第1位置1
(*(volatile unsigned long int *)(unsigned long int) 0x2205FE04)=1;
4.2利用位带技术提高LED点阵数量的编程实例
在嵌入式系统设计中,对于内存的访问操作十分频繁。下面以笔者设计的一个实际项目案例来说明位带技术在内存访问控制上的优势。
所设计的单色16×16点阵LED屏移动显示控制系统中,LED点阵屏采用动态扫描方案,使用MCU进行控制扫描。在屏幕点亮前需要将内存中一个字节的数据一位一位串行送入控制芯片74HC595中[8],对于送一个字节数据,程序段需要反复调用执行。在设计中使用了两种方法进行编程,各有优劣,下面就以实际案例程序进行分析说明。
4.2.1内存数据移位法
该方法利用循环实现将内存*data变量中的数据和i变量进行与操作,i初值为0b1000000。循环首次判断*data最高位的值,如果是0则将一位数据0送入595;如果是1则将一位数据1送入595,然后将i右移1位,判断下一位。循环8次实现将一个字节中的数据逐位送入595芯片。利用C语言的基本位操作语句实现,程序可读性和可移植性较好。
void LED_Sendbyte(uint_8 *data)
{uint_8 i,j;
//GPIOA组寄存器的D16位对应PORTC0,决定PORTC0引脚
//的控制,依次类推
volatile uint_32 *PC=(uint_32*)0x400FF000u;
//将一个字节,送入595(数据上线)
i=0b10000000;
//为了取字节中的一位
for (j = 1; j <=8 ; j++)
//对一个字节循环
{ *PC &= ~(1<<16);
//使CLK为0
((*data&i)==0)?(*PA |= 0b00010000):(*PA &=0b11101111);
//CLK产生上升沿,使数据送到595移位寄存器
*PC |= (1<<16);
//使CLK为1
//i右移一位,为取data_byte字节中的一位做准备
i=i>>1;
}
}
4.2.2位带技术法
该方法是利用位带技术访问存储空间,修改链接文件中堆栈SP地址_estack = 0x20003000-0x20,空出32个字节用于位带区,防止内存的访问冲突[9]。利用语句volatile uint_32 *temp=(uint_32*)0x20002FF0定义将需要送入595芯片的内存数据存入SRAM_U位带区的固定地址0x20002FF0处。通过位带技术可以直接访问位带区所对应的位带别名区,根据公式可以计算出SRAM_U位带区0x20002FF0的一个字节8个位所对应的位带别名区的映射地址为:0x2205FE1C-0x2205FE00。程序通过对位带别名区的地址读取判断,实现将0或1一位数据送入595芯片。
编译后会生成极少代码,尤其大大减少了程序执行的指令周期,提高程序运行速度。程序设计时可以利用宏定义预先计算出对应的映射地址,在程序中直接使用宏,增加程序的可读性和可维护性。
void LED_Sendbyte( )
{//GPIOA组寄存器的D16位对应PORTC0,决定PORTC0引脚的
//控制,依次类推
volatile uint_32 *PC=(uint_32*)0x400FF000u;
//送出第7位,送入595(数据上线)
*PC &= ~(1<<16);
//使CLK为0
((*(volatile uint_32 *) (uint_32)0x2205FE1C)==0)?(*PA |= 0b00010000):(*PA &=0b11101111);
//CLK产生上升沿,使数据送到595移位寄存器
*PC |= (1<<16);
//使CLK为1
//送出第6位,送入595(数据上线)
*PC &= ~(1<<16);
//使CLK为0
((*(volatile uint_32 *) (uint_32)0x2205FE18)==0)?(*PA |= 0b00010000):(*PA &=0b11101111);
//CLK产生上升沿,使数据送到595移位寄存器
*PC |= (1<<16);
//使CLK为1
//依次送出第5、4、3、2、1、0位,送入595(数据上线)
//后续程序段由于篇幅关系,此处省略。重复上述程序段,只需将
//位带别名区的地址依次修改为: 0x2205FE14、0x2205FE10、0x2205
//FE0C、0x2205FE08、0x2205FE04、0x2205FE00即可。
}
4.2.3实现技术性能比较
随着KEA128微控制器所控制的16×16点阵LED屏数量的增多,所显示点阵汉字字节数(一块屏幕显示一个汉字,需要送入32字节的数据给74HC595)急剧上升,上述LED_Sendbyte“字节数据上线”函数代码的重复运行次数会急剧增加。笔者使用Kinetis Design Studio 2.0.0编译软件对上述两种程序代码进行编译,下载至芯片。在KEA128芯片使用内部时钟运行于24 MHz时[3],以点阵LED屏显示内容不闪烁为标准,实际测试了两种技术方法最大所支持的点阵LED屏数量和反汇编所生产的机器指令数目,如表1所示。
表1 不同技术方法性能对比
从表1可知,位带技术法比内存移位法程序执行效率提高了213%,所生成的机器指令数目减少了57%。使用位带技术访问内存的程序代码执行效率远高于普通内存访问方法。在上述实际案例项目中使用位带技术优化代码进行控制扫描,使用单块MCU就可以实现控制64块点阵屏的汉字的移动显示,从而可以节省硬件成本。
5 结 语
本文介绍了飞思卡尔KEA128微控制器硬件所支持的位带技术,通过实例分析验证了技术的优越性;给出解决多任务间共享资源的“互锁”问题和位带技术提高LED点阵数量的编程实际应用案例,为其他编程人员提供参考。在嵌入式程序设计中使用位带技术,比使用普通C语言实现相同功能的代码,可以提高MCU的位操作性能,减少C代码的指令大小,减少程序运行时间,提高了指令执行效率。本文所采用的KEA128芯片在汽车电子应用中会出现快速控制汽车电子器件的情况,使用位带技术尤其适合嵌入式系统中对SRAM_U快速位操作的场合,对于在内核资源紧张的时候可以给用户提供一个精简代码和提高程序执行速度的手段。其能够降低总线的占用率和CPU执行时间,降低系统的功耗。
[1] 张吉豫,刘先华,谭明星,等.一种针对位操作密集应用的扩展指令自动选择方法[J].电子学报,2012,40(2):209-214.
[2] Freescale.KEA128 Sub-Family Reference Manual Rev 2[EB/OL].2014:223-240.http://www.Freescale.com.
[3] Freescale.KEA128 Sub-Family Data Sheet Rev 4[EB/OL].2014:20-21.http://www.Freescale.com.
[4] ARM.Cortex-M0+Devices Generic User Guide[EB/OL].2012:54-57.http://www.ARM.com.
[5] Hilewitz Y,Lee R B.A new basis for shifters in general-Purpose processors for existing and advanced bit manipulations[J].IEEE Transactions on Computers,2009,58(8):1035-1048.
[6] 唐飞,王陈宁,查长礼.位带技术在STM32程序设计中的应用[J].安庆师范学院学报:自然科学版,2014,20(1):54-57,76.
[7] 王晓春,刘兴东.嵌入式实时操作系统任务的同步与互斥机制[J].计算机测量与控制,2004,12(6):578-580.
[8] 张飙.LED显示屏控制器设计研究[J].计算机应用与软件,2011,28(3):188-190.
[9] 王宜怀,朱仕浪,郭芸.嵌入式技术基础与实践—ARM Cortex-M0+ Kinetis L系列微控制器[M].3版.北京:清华大学出版社,2013.
ANALYSING APPLICATION OF BIT-BAND IN FREESCALE’S KEA128 MICROCONTROLLER
Li Yuehua1,2Wang Yihuai2
1(SchoolofComputerScienceandTechnology,NantongUniversity,Nantong226019,Jiangsu,China)2(SchoolofComputerScienceandTechnology,SoochowUniversity,Suzhou215006,Jiangsu,China)
When developing embedded system, “read-modify-write” operations have to be used to access the memory, and this will produce at least three machine instructions, and is not suitable for the occasions requiring high implementation speed. In addition this may also lead to the problem of "interlocking" in sharing resources between multi-tasks. This paper analyses in detail the working mechanism of bit-band technique, which is provided by KEA128 microcontroller’s hardware, on bit operations of SRAM_U memory. By comparative analysis of examples and application results it is shown that the use of bit-band technology can reduce the space occupied by the code, as well as reduce the machine instruction cycle of program execution, and is suitable for programmers to use this technology in advanced programming to achieve fast "atomic operation" on bits and to improve the speed of program execution as well.
SRAM_UBit-band regionAliased bit-band regionAtomic operationInterlock
2015-06-16。国家自然科学基金项目(60871086);南通市应用研究项目(BK2012068)。李跃华,副教授,主研领域:嵌入式与物联网技术。王宜怀,教授。
TP391
A
10.3969/j.issn.1000-386x.2016.10.048