newlib在uCOS3上的实现


最近给刚移植到s3c2440平台的uCOS3加入newlib库支持。

使用sourcery G++编译工具链,sourcery G++ 带有编译好的newlib库。我们要使用的时候只要链接libc.a他就可以了。(我使用eclipse+arm补丁为开发环境)

要使用newlib则首先要实现20个newlib桩函数:_open_r()  _read_r() _write_r()等(具体看newlib文档);然后要实现文件描述符等。

文件描述符的实现将来再写。。。

下面主要说一下移植的一些关键问题:

int main (void)
{
    ...
    stdin  = fopen((const char *)"/dev/ttyS0", "r+");   
    stdout = fopen((const char *)"/dev/ttyS0", "w+");             
    stderr = fopen((const char *)"/dev/ttyS0", "w+"); 
    errno  = 1;  /* test errno */
    printf("printf test \n");
    perror("error");
    ...
}

这样我们就可以使用printf 和perror两个函数了。

 stdin、errno 等这些宏都是针对他们所在任务的:

#define _REENT   _impure_ptr
#define stdin       (_REENT->_stdin)
#define errno      (*__errno())
int *__errno ()
{ 
    return &_REENT->_errno;
}
所以全局指针 _impure_ptr 要在任务切换的时候指向每个任务的reent实例:

void  App_OS_TaskSwHook (void)
{
    _impure_ptr = &OSTCBHighRdyPtr->reent;      /* newlib 中可重入对象指针切换实例*/
}

给uCOS3的任务控制块TCB加入成员:

struct os_tcb {
    ...
    struct _reent       reent;   /* 每个任务要有一个具体的reent实例*/
}


任务创建的时候(OSTaskCreate())要给每个任务控制块的成员reent初始化:

void OSTaskCreate (...)
{
    ...
    _REENT_INIT_PTR(&p_tcb->reent);                         /* 初始化 reent */
    /*
     * 该函数会默认初始化stdin、stdout、stderr的fd为0,1,2
     * 若不调用该函数,则printf检查到为初始化reent则会调用该函数,这样stdout=fopen(...),
     * 给stdout赋值好后会在printf后重新被初始化掉,所以在这里初始化。
     */
    CHECK_STD_INIT(&p_tcb->reent);
    /*
     * 由于CHECK_STD_INIT()初始化stdin、stdout、stderr的fd为0,1,2,
     * 这样导致即使任务中没给stdout赋值,只要fd=1的设备默认就是stdout,所以清除掉std指针
     */
    p_tcb->reent._stdin  = NULL;
    p_tcb->reent._stdout = NULL;
    p_tcb->reent._stderr = NULL;
    ...
} 


以上之所以要这么初始化,是因为printf在调用的时候若发现未初始化当前任务reent,则会初始化reent,初始化的reent._stdin->file = 0,reent._stdout->file = 1,reent._stderr->file = 2,这就意味着之前的stdout = fopen((const char *)"/dev/ttyS0", "w+"); stdout赋值无效,会被重新初始化掉,当然如果你打开的顺序正好是按stdin stdout stderr 即fd 为 0, 1,2 则使用的时候也不出出现问题,但是这样我们给stdout赋值是没有起到实际效果的,只是恰好被分配到 fd为0,1,2.


先到这里了,详细内容将来再整理吧。。。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值