引言<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><?xml:namespace prefix = w ns = "urn:schemas-microsoft-com:office:word" />
用过NIOS的朋友都会体会到NIOS那笨拙的编译器编译出的代码有多么庞大。没有SDRAM的FPGA系统想架构NIOS是一件多么困难的事情,因为仅仅一句printf就要占去几十K的存储空间,真是让人望而却步。今天我们这个专题就是为那些没有SDRAM却又想试试NIOS强大功能的朋友们准备的。
如何减少代码量
废话少说,切入正题:NIOS减小代码量的方法有很多,大家按照如下设置,就可以轻松将自己的C代码优化到最小尺寸。
1.采用alt_main( )作为程序入口
NiosII处理器的启动可采用两种方式:自动初始化和用户自定义初始化。ANSI C标准定义应用程序可以通过调用main()来开始执行。在调用main()之前,应用程序假定运行环境和所有的服务系统都被初始化并准备运行。初始化可以被硬件抽象层(HAL)系统库自动执行。程序员不需要考虑系统的输出设备以及如何初始化每一个外设,HAL会自动初始化整个系统。
HAL提供的系统初始化代码按以下启动顺序运行:
① 启动指令和数据高速缓冲存储器;
② 配置堆栈;
③ 配置全局指针;
④ 通过链接器提供的_bss_start和_bss_end来零初始化BSS层,_bss_start和_bss_end 是开始和结束BSS的命令;
⑤ 如果当前系统没有启动下载器,就复制.rwdata、.rodata,或者剩下的部分到RAM;
⑥ 调用alt_main()。
如果不调用alt_main()函数,则系统默认运行步骤如下:
① 调用ALT_OS_INIT()来执行任何操作系统所特有的初始化。如果HAL是在操作系统里运行的,那么初始化alt_fd_list_lock命令。它可以控制访问HAL文件系统,初始化中断控制器并执行中断;
② 调用alt_sys_init()函数,以初始化系统里所有的驱动装置和软件组成部分;
③ 重新设置C标准I/O通道(stdin,stdout,stderr),以使用合适的器件
④ 调用main();
⑤ 调用exit(),main()的返回代码作为exit()的输入。
看看吧,如果不编写自己的alt_main()函数,NIOS将会默认执行所有的初始化过程,显然耗费了大量的初始化代码。所以如果我们够牛,或者我们的程序使用的硬件足够容易,能手动初始化任何所用的硬件。则可以采用alt_main()函数完全控制系统的初始化,手动编写初始化系统的代码以减小代码量,其格式如下
int main (void) __attribute__ ((weak, alias ("alt_main"))); int alt_main (void)
|
使用独立式编程环境会增加NiosII程序编写的复杂性。独立式编程环境的主要作用在于减小代码量,但要使用这种方法,需要对NiosII处理器的外设和驱动编写都非常熟悉才行。所以啊,为了少出问题,最好大家谨慎使用。比如如果使用了alt_main,则中断控制器必须手动初始化,在alt_main开始加入alt_irq_init (ALT_IRQ_BASE)才行。但是当用main代替alt_main时,不需要alt_irq_init 中断也能运行。所以使用好这一招还是比较麻烦的。不过别担心,在NiosII IDE中也可以通过某些选项来减小HAL系统库容量,从而达到减小代码量的目的,那可是完全傻瓜化,比使用独立式编程环境容易得多。
2. 打开编译器优化选项
在nios2-elf-gcc编译器中使用“-O3”选项,代码可以被最大限度地优化,包括代码的大小和执行速度。需要注意的是,编译器优化可能会带来一些意想不到的结果。另外,必须在用户工程和系统库中都使用-O3选项,如图所示。
3 使用小封装的驱动库与C语言库等
HAL为处理器的外设提供了两种驱动库: 一种是执行速度快,但代码量大的版本;另一种是小封装版本。默认情况下,HAL系统使用是代码量大的版本。可以选择Reduced device drivers选项来选择小封装版本,从而减小代码量。
完整的ANSI C标准库通常不适用于嵌入式系统,HAL提供了一系列经过裁减的新的ANSI C标准库,占用非常小的代码量。可以选择Small C library选项来选择新的ANSI C标准库,此外还推荐勾选如图配置,Program never exits表示程序永远不会结束,则系统可以省去exit代码,还有最好使用纯C语言编程,不要使用C++。
4 去掉不使用的驱动库
当NiosII系统中有外设时,NiosII IDE认为这些设备需要驱动,因此在HAL系统中加入了相应的驱动库。如果在用户的程序中并不需要使用到这些外设,也可以在初始化时不加载这些驱动库。当用户的程序并没有使用到NiosII系统中某些设备时,应在系统中将这些设备完全移除。这样,既可以减小软件代码量,又可以减少占用的FPGA资源。
测试与总结
拿个例子测试一下吧,最简单的流水灯吧。不去优化它,编译一下….
晕死,怎么那么大,4KB的片内存储器都放不下,疯了,居然还差1104B….
没事,我们有绝招!
按照上面说的,全部设置完毕,编译….
看看我们的优化成果吧,哈哈,仅用了400多字节的代码与初始化数据,对于ONCHIP存储器来说也是小菜一碟,没有SDRAM的板子也能跑起NIOS啦!
注意:虽然优化可以有效减少代码量,但有的时候也会带来意想不到的问题。所以大家请慎用。遇到异常时,先关闭优化,CLEAN代码后再次编译,测试一下是否是优化所致。 |
https://static.assets-stash.eet-china.com/album/old-resources/2010/6/29/6fbbd9c4-cf92-4271-a81e-0207731afed4.rar" target=_blank>
文章评论(0条评论)
登录后参与讨论