RSS

在VIVI中使用GNU标准库stdarg.h实现printk

来源:网络 作者:匿名 时间:2007-01-06 Tag: 点击:

一个朋友在读代码的时候,问我嵌入式loader里面是否可以用标准库,我根据我读过的loader的经验回答他说一般是不可以的。
   然后朋友要我看s3c2410 vivi代码的printk.c中417行??va_list args;args是用标准库中stdarg.h中的va_list定义的。然后函数中还用了void va_start (va_list ap, last-required),void va_end (va_list ap),都是GNU C Library函数.
   我想在这简单记录一下标准库stdarg.h。然后分析一下VIVI 中printk函数的实现。

一、stdarg.h库介绍:

1.1、stdarg.h库描述。
     在<stdarg.h>中声明了宏vararg解决了传递给函数的参数个数以及类型都不确定的问题。这种函数至少有一个固定参数。函数原型的参数列表必须包含"..."以表明不定参数的开始。告诉编译器,当向这个函数传递额外的而且类型似乎不一致的参数时不报错。
     stdarg还提供了把一个函数的不定参数传递给另一个函数的途径,这种途径安全而且具有可移植性。这种功能最常见的用法之一就是编写自己的printf风格的函数,而这个函数反过来又使用已有的函数来实现。

1.2、stdarg.h库GNU文档描述。
Data Type: va_list
The type va_list is used for argument pointer variables.

Macro: void va_start (va_list ap, last-required)
This macro initializes the argument pointer variable ap to point to the first of the optional arguments of the current function; last-required must be the last required argument to the function.
Macro: type va_arg (va_list ap, type)
The va_arg macro returns the value of the next optional argument, and modifies the value of ap to point to the subsequent argument. Thus, successive uses of va_arg return successive optional arguments.
          The type of the value returned by va_arg is type as specified in the call. type must be a self-promoting type (not char or short int or float) that matches the type of the actual argument.
Macro: void va_end (va_list ap)
This ends the use of ap. After a va_end call, further va_arg calls with the same ap may not work. You should invoke va_end before returning from the function in which va_start was invoked with the same ap argument.
Macro: void __va_copy (va_list dest, va_list src)
The __va_copy macro allows copying of objects of type va_list even if this is not an integral type. The argument pointer in dest is initialized to point to the same argument as the pointer in src.

二、VIVI中printf函数的实现。

2.1、源码:
int printk(const char *fmt, ...)
{
 va_list args;  //#include <stdarg.h>
 int printed_len;
 char *p;
 static char printk_buf[1024];

 /* Emit the output into the temporary buffer */
 va_start(args, fmt);
 printed_len = vsnprintf(printk_buf, sizeof(printk_buf), fmt, args);
 va_end(args);

 /*
  * Copy the output into log_buf.  If the caller didn't provide
  * appropriate log level tags, we insert them here
  */
 for (p = printk_buf; *p; p++) {
  if (*p == '\n')
   PUTC('\r');
  PUTC(*p);
 }

 return printed_len;
}

2.2、函数分析
    1、va_start(args,fmt);使args指向当前函数的第一个参数。
    2、vsnprint();返回存储的字符的数目,若为-1表示输出字符的空间不够。
    3、va_end();释放args指向的空间。
    4、使用for循环打印字符。


1.部分资源来自网络,经ET电子归类整理,旨在服务电子爱好者并无商业目的,不保证正确性与完整性.
2.如果您觉得本站资源对您有用,请告知您的好友,用搜索引擎搜"ET电子"即可.


最新评论共有 0 位网友发表了评论
发表评论
评论内容:不能超过250字,需审核,请自觉遵守互联网相关政策法规。
用户名: 密码:
匿名?
注册
教程下载