如何在嵌入式系统中使用C库(SDT开发环境)

在嵌入式系统开发中,可以根据需要选择是否采用C库,如果应用程序较大,可能需要经常使用C库中的一些函数,如需要使用动态分配内存mallocfreestdio.h中的printfsprintfstring.h中的strcmpstrcpy等等。这时移入合适的C库是很好的选择,本文主要讲述在SDT2.5版本的ARM编译开发工具中使用C库需要解决的一些问题。

    SDT2.5版本的开发环境中,可以采用semihosted ANSI C library或者Embedded C libraryEmbedded C只是作为ANSI C的一个子集。ANSI C一般适用于早期的开发工作,可以和AngleARMulator等软件调试工具配合使用,方便软件的开发,在用户自己的代码执行之前,使用库前,所有的系统初始化工作必须完成。后者由于代码更小,不使用底层硬件资源,在与应用程序集成的时候比较适合与最终的版本发布。而且配合一些硬件调试仿真工具,对于程序的调试来讲,应该非常方便。

    Embedded C library应用程序执行流程:

1.系统启动之后,底层的一些初始化,

   在跳转到C程序前,必须用汇编完成一些底层的一些初始化工作,只有包括异常中断跳转地址的处理,根据嵌入式系统的需要是否采用remap,以及异常中断的处理等等。

2.初始化嵌入式堆栈管理器

   C程序中,一般都需要采用动态分配内存,可以调用嵌入式C库中的堆管理器,根据堆的位置和大小来初始化堆,以便在C程序可以用malloc()函数动态分配内存。具体的动态内存分配算法在下面会继续阐述。

   初始化调用的函数是:

    struct Heap_Descriptor *__rt_embeddedalloc_init(void *base, size_t size);

该函数返回一个堆描述符的指针。

由于嵌入式C库被设计成可以完全可重入的,不包含静态数据,用户在自己的代码中必须提供回调函数 struct Heap_Descriptor *__rt_heapdescriptor(void),该函数返回__rt_embeddedalloc_init()的值,这样库可以根据返回值定位堆描述符。

3.调用顶层对象构建器

   如果在嵌入式C库中使用C++库,则需要调用顶层对象构建器void __cpp_initialise(void)

4.执行主程序

5.调用顶层对象析构器

   在程序终断前,必须调用顶层对象析构器 void _cpp_finalise(void)

 

   代码实例:

include

 

extern struct Heap_Descriptor *__rt_embeddedalloc_init(void *base, size_t size);

void ApplicationCode(void);

struct Heap_Descriptor *hp;

 

extern struct Heap_Descriptor *__rt_heapdescriptor(void) {

    return hp;

}

 

extern void C_Entry(void) {

    hp = __rt_embeddedalloc_init((void *)0x2030000, 0x20000);

    ApplicationCode();

}

 

使用Embedded C library其他需要注意的地方:

1)在SDT编译环境中,armlink选项的库搜索路径选择/arm/lib/embedded/,该目录下有四个库文件,分别对应16biglittle32biglittle

2)代码必须重新实现实现__main(),_main(),不然在SDT下编译会出错。

3 )如果使用 c 库函数,根据需要可能还要实现 __rt_trap, __rt_errno_addr, __rt_ft_status_addr ,具体实现同 __rt_heapdescriptor(), 但在 SDT 下不会编译出错,在 symbol table 中会出现 undefinded weak reference 信息。

你可能感兴趣的:(c,struct,嵌入式,library,reference,Descriptor)