微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > S3C2440开发工具realview MDK4.22之库的使用

S3C2440开发工具realview MDK4.22之库的使用

时间:11-19 来源:互联网 点击:

1个fputc()的实现是半主机的。可以提供这两个版本,具体要看传递到函数的FILE指针的性质。

int $Super$fputc(int c, FILE *fp);int $Sub$fputc(int c, FILE *fp){if (fp == (FILE *)MAGIC_NUM) // where MAGIC_NUM is a special value that{                            // is different to all normal FILE * pointer// values.write_to_UART(c);return c;}else{return $Super$fputc(c, fp);}}
可以看到根据FILE指针判断是哪种类型,$$super$代表正常的,$$sub$代表特殊的,一般和自己的目标硬件相关。

十二。以非半主机模式使用库

一些C库函数使用半主机。如果不想使用的话,下列方式之一可以实现:

1.移除所有的半主机函数调用

2.重定义低层函数,比如fputc()。不必重定义所有的半主机函数。只是重定义在程序里需要使用到的函数。

有些函数虽然不直接与目标依赖,但是它依赖于某些底层函数,而底层函数依赖于目标。例如,printf(),你必须重定义fputc(),如果不用得话,那就不必重定义了。

3.以自己特别的方式实现所有半主机调用的一种方式。一个作为这种处理的例子是,拦截调用,将它们重指向自己的非主机实现,也就是,具体目标的函数。

IMPORT __use_no_semihosting from ASM

#pragma import(__use_no_semihosting) from C

十三。直接的半主机依赖


十四。间接的半主机依赖


十五。建立一个不使用C库的应用程序

如果程序中不包含main(),那么库不会被初始化,且如下功能不可用:

1.带有_sys_前缀的底层stdio函数

2.信号处理函数

3.其它函数,如atexit()

有些函数即便库未初始化也能使用,一些其它不可用的函数也能被使用,除非它们所依赖的库函数被重定义。

十六。裸机代码

如果你写一个程序,里面没有使用库,且没有任何环境初始化,你必须:

1.如果用到heap的话,重定义__rt_raise()

2.不定义main()

3.写一个汇编语言代码建立c语言运行需要的环境,必须要跳转到你c函数的入口

4.提供自己的RW/ZI初始化代码

5.确保你的汇编代码在你的重启处理段

6.用--fpu=none

当满足这些要求,连接器用合适的C库变体寻找任何需要编译的函数,它们是隐形调用的。

尽管没有main(),__user_lbspace()被自动创建,占用96字节的ZI段。

十七。定制C库启动代码且访问C库函数

应用程序里不需要C库,如果你程序里有main(),连接器会自动包含初始化代码。可能存在一些情况,这是不必的。例如,一个运行RTOS系统可能通过RTOS启动代码

有它自己的执行环境配置。

你可以创建一个应用包含自己的启动代码且仍然可以使用库函数的大部分功能。你可以做下列之一的选择:

1.避免使用需要初始化的函数

2.提供初始化和底层函数函数实现

十八。利用C库使用底层函数

如果你的应用中没有main(),而使用库的话,必须重定义一些在库里的函数

注意:如果用heap的话,__rt_raise()是必须的。

十九。利用库中的高层函数

如果低层的函数被重定义了,那么高层I/O函数能被使用。高层函数是像fprintf() printf() scanf() puts()等,低层函数是那些如fputc() fgetc() 以及__backspace()函数。

大多数格式化输出函数也需要调用setlocale()。

二十。利用库中的malloc()函数

如果在裸机C代码中需要堆得支持,那么__init_alloc()必须要首先调用支持堆的边界初始化,__rt_heap_extend()必须要提供,尽管返回失败。如果没有__rt_heap_extend()函数,特定的库功能会被包含进去,这会导致裸机C代码出现问题。

二十一。执行环境的初始化和程序的执行

一个程序的入口是位于C库里的__main,它会做如下事情:

1.拷贝非根区代码从它们的加载地址到运行地址。如果任何数据段被压缩了得话,它们也会被解压缩。

2.用0初始化ZI区。

3.跳转到__rt_entry。

如果你不想C库做这些事情,你可以定义自己的__main,__main里可以跳转到__rt_entry。例如:

IMPORT __rt_entryEXPORT __mainENTRY__mainB  __rt_entryEND
库函数__rt_entry像下面这样运行程序:

1.建立堆和栈通过以下方式之一:调用__user_setup_srackheap(),调用__rt_stackheap_int()或加载scatter文件里的绝对地址。

2.调用__rt_lib_init()初始化引用的库函数,初始化locale,如果必要的话,为main()建立argc和argv。

3.调用main(),用户级的根函数。

4.从main()函数起,你的程序可能调用库函数。

5.利用main()返回的数值作为参数调用exit()函数。

二十二。在main()里调用库函数

.main()是用户级的根函数。它需要已经初始化了的执行环境和可以使用的输入输出函数。在main()里程序可能执行下列的动作之一,下列动作调用了用户定制的C库函数:

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top