📄 libc.sgml
字号:
<PARA>Here are some details about the <!-- <index></index> -->implementation
which might be interesting, although they do not affect the ISO-defined
semantics of the library. </PARA>
<ITEMIZEDLIST>
<LISTITEM>
<PARA>It is possible to configure
<EMPHASIS>eCos</EMPHASIS>
to have the standard C library without the kernel. You might want
to do this to use less memory. But if you disable the kernel, you
will be unable to use memory allocation, thread-safety and certain
stdio functions such as input. Other C library functionality is
unaffected.</PARA>
</LISTITEM>
<LISTITEM>
<PARA>The opaque type returned by
<FUNCTION>clock()</FUNCTION>
is called clock_t, and is implemented as a 64 bit integer.
The value returned by
<FUNCTION>clock()</FUNCTION>
is only correct if the kernel is configured with real-time clock
support, as determined by the CYGVAR_KERNEL_COUNTERS_CLOCK
configuration option in
<FILENAME>kernel.h</FILENAME>
.</PARA>
</LISTITEM>
<LISTITEM>
<PARA>The FILE type is not implemented as a structure, but rather
as a CYG_ADDRESS. </PARA>
</LISTITEM>
<LISTITEM>
<PARA>The GNU C compiler will place its own <EMPHASIS>built-in</EMPHASIS> implementations
instead of some C library functions. This can be turned off with
the <EMPHASIS>-fno-builtin</EMPHASIS> option. The functions affected
by this are
<FUNCTION>abs()</FUNCTION>
,
<FUNCTION>cos()</FUNCTION>
,
<FUNCTION>fabs()</FUNCTION>
,
<FUNCTION>labs()</FUNCTION>
,
<FUNCTION>memcmp()</FUNCTION>
,
<FUNCTION>memcpy()</FUNCTION>
,
<FUNCTION>sin()</FUNCTION>
,
<FUNCTION>sqrt()</FUNCTION>
,
<FUNCTION>strcmp()</FUNCTION>
,
<FUNCTION>strcpy()</FUNCTION>
, and
<FUNCTION>strlen()</FUNCTION>
.</PARA>
</LISTITEM>
<LISTITEM>
<PARA>For faster execution speed you should avoid this option
and let the compiler use its built-ins. This can be turned off by
invoking
<EMPHASIS>GCC</EMPHASIS>
with the <EMPHASIS>-fno-builtin</EMPHASIS> option. </PARA>
</LISTITEM>
<LISTITEM>
<PARA><FUNCTION>memcpy()</FUNCTION>
and
<FUNCTION>memset()</FUNCTION>
are located in the infrastructure package, not in the C library
package. This is because the compiler calls these functions, and
the kernel needs to resolve them even if the C library is not configured. </PARA>
</LISTITEM>
<LISTITEM>
<PARA>Error codes such as EDOM and ERANGE, as well as
<FUNCTION>strerror()</FUNCTION>
, are implemented in the <EMPHASIS>error</EMPHASIS> package. The
error package is separate from the rest of the C and math libraries
so that the rest of
<EMPHASIS>eCos</EMPHASIS>
can use these error handling facilities even if the C library is
not configured. </PARA>
</LISTITEM>
<LISTITEM>
<PARA>When
<FUNCTION>free()</FUNCTION>
is invoked, heap memory will normally be coalesced. If the CYGSEM_KERNEL_MEMORY_COALESCE
configuration parameter is not set, memory will not be coalesced,
which might cause programs to fail. </PARA>
</LISTITEM>
<LISTITEM>
<PARA>Signals, as implemented by
<filename><signal.h></filename>, are guaranteed to work
correctly if raised using the
<FUNCTION>raise()</FUNCTION>
function from a normal working program context. Using signals from
within an ISR or DSR context is not expected to work. Also, it is
not guaranteed that if CYGSEM_LIBC_SIGNALS_HWEXCEPTIONS
is set, that handling a signal using
<FUNCTION>signal()</FUNCTION>
will necessarily catch that form of exception. For example, it
may be expected that a divide-by-zero error would be caught by handling
<varname>SIGFPE</varname>. However it depends on the underlying HAL implementation to implement
the required hardware exception. And indeed the hardware itself
may not be capable of detecting these exceptions so it may not be
possible for the HAL implementer to do this in any case. Despite
this lack of guarantees in this respect, the signals implementation
is still ISO C compliant since ISO C does not offer any such guarantees
either. </PARA>
</LISTITEM>
<LISTITEM>
<PARA>The
<FUNCTION>getenv()</FUNCTION>
function is implemented (unless the CYGPKG_LIBC_ENVIRONMENT configuration
option is turned off), but there is no shell or
<FUNCTION>putenv()</FUNCTION>
function to set the environment dynamically. The environment is
set in a global variable environ, declared as:</PARA>
<PROGRAMLISTING>extern char **environ; // Standard environment definition</PROGRAMLISTING>
<PARA>The environment can be statically initialized at startup time
using the CYGDAT_LIBC_DEFAULT_ENVIRONMENT
option. If so, remember that the final entry of the array initializer
must be NULL. </PARA>
</LISTITEM>
</ITEMIZEDLIST>
<PARA>Here is a minimal <EMPHASIS>eCos</EMPHASIS> program which
demonstrates the use of environments (see also the test case in <filename>language/c/libc/current/tests/stdlib/getenv.c</filename>): </PARA>
<PROGRAMLISTING>#include <stdio.h>
#include <stdlib.h> // Main header for stdlib functions
extern char **environ; // Standard environment definition
int
main( int argc, char *argv[] )
{
char *str;
char *env[] = { "PATH=/usr/local/bin:/usr/bin",
"HOME=/home/fred",
"TEST=1234=5678",
"home=hatstand",
NULL };
printf("Display the current PATH environment variable\n");
environ = (char **)&env;
str = getenv("PATH");
if (str==NULL) {
printf("The current PATH is unset\n");
} else {
printf("The current PATH is \"%s\"\n", str);
}
return 0;
} </PROGRAMLISTING>
</SECT1>
<SECT1 id="libc-thread-safety">
<TITLE><!-- <index></index> -->Thread safety</TITLE>
<PARA>The ISO C library has configuration options that control thread
safety, i.e. working behavior if multiple threads call the same
function at the same time.</PARA>
<PARA>The following functionality has to be configured correctly,
or used carefully in a multi-threaded environment:</PARA>
<ITEMIZEDLIST>
<LISTITEM>
<PARA><function>mblen()</function></para>
</listitem>
<listitem>
<para><function>mbtowc()</function></para>
</listitem>
<listitem>
<para><function>wctomb()</function></para>
</listitem>
<listitem>
<para>
<FUNCTION>printf()</FUNCTION>
(and all standard I/O functions except for
<FUNCTION>sprintf()</FUNCTION>
and
<FUNCTION>sscanf()</FUNCTION></PARA>
</LISTITEM>
<LISTITEM>
<PARA><FUNCTION>strtok()</FUNCTION></PARA>
</LISTITEM>
<LISTITEM>
<PARA><FUNCTION>rand()</FUNCTION>
and
<FUNCTION>srand()</FUNCTION></PARA>
</LISTITEM>
<LISTITEM>
<PARA><FUNCTION>signal()</FUNCTION>
and
<FUNCTION>raise()</FUNCTION></PARA>
</LISTITEM>
<LISTITEM>
<PARA><FUNCTION>asctime()</FUNCTION>
,
<FUNCTION>ctime()</FUNCTION>
,
<FUNCTION>gmtime()</FUNCTION>
, and
<FUNCTION>localtime()</FUNCTION></PARA>
</LISTITEM>
<LISTITEM>
<PARA>the
<FUNCTION>errno</FUNCTION>
variable</PARA>
</LISTITEM>
<LISTITEM>
<PARA>the
<FUNCTION>environ</FUNCTION>
variable</PARA>
</LISTITEM>
<LISTITEM>
<PARA>date and time settings</PARA>
</LISTITEM>
</ITEMIZEDLIST>
<PARA>In some cases, to make <EMPHASIS>eCos</EMPHASIS> development
easier, functions are provided (as specified by POSIX 1003.1) that define
re-entrant alternatives, i.e. <FUNCTION>rand_r()</FUNCTION>, <FUNCTION>strtok_r()</FUNCTION>, <FUNCTION>asctime_r()</FUNCTION>, <FUNCTION>ctime_r()</FUNCTION>, <FUNCTION>gmtime_r()</FUNCTION>,
and <FUNCTION>localtime_r()</FUNCTION>. In other cases,
configuration options are provided that control either locking of functions
or their shared data, such as with standard I/O streams,
or by using per-thread data, such as with the <FUNCTION>errno</FUNCTION> variable.</PARA>
<PARA>In some other cases, like the setting of date and time, no
re-entrant or thread-safe alternative or configuration is provided
as it is simply not a worthwhile addition (date and time should
rarely need to be set.)</PARA>
</SECT1>
<SECT1 id="c-library-startup">
<TITLE><!-- <index></index> --><!-- <xref> -->C library startup</TITLE>
<PARA>The C library includes a function declared as:</PARA>
<PROGRAMLISTING>void <FUNCTION>cyg_iso_c_start</FUNCTION>( void )</PROGRAMLISTING>
<PARA>This function is used to start an environment in which an
ISO C style program can run in the most compatible way.</PARA>
<PARA>What this function does is to create a thread which will invoke <FUNCTION>main()</FUNCTION> — normally
considered a program's entry point. In particular, it can
supply arguments to <FUNCTION>main()</FUNCTION> using the CYGDAT_LIBC_ARGUMENTS
configuration option, and when returning from <FUNCTION>main()</FUNCTION>,
or calling <FUNCTION>exit()</FUNCTION>, pending stdio file output
is flushed and any functions registered with <FUNCTION>atexit()</FUNCTION> are
invoked. This is all compliant with the ISO C standard in this respect. </PARA>
<PARA>This thread starts execution when the <EMPHASIS>eCos</EMPHASIS> scheduler
is started. If the <EMPHASIS>eCos</EMPHASIS> kernel package is not
available (and hence there is no scheduler), then <FUNCTION>cyg_iso_c_start()</FUNCTION> will
invoke the <FUNCTION>main()</FUNCTION> function directly, i.e.
it will not return until the <FUNCTION>main()</FUNCTION> function
returns. </PARA>
<PARA>The <FUNCTION>main()</FUNCTION> function should be defined
as the following, and if defined in a C++ file,
should have “C” linkage: </PARA>
<PROGRAMLISTING>extern int <FUNCTION>main</FUNCTION>(
int <EMPHASIS>argc,</EMPHASIS>
char *<EMPHASIS>argv[] </EMPHASIS>)</PROGRAMLISTING>
<PARA>The thread that is started by <FUNCTION>cyg_iso_c_start()</FUNCTION> can
be manipulated directly, if you wish. For example you can suspend
it. The kernel C API needs a handle to do this, which is available
by including the following in your source code.</PARA>
<PROGRAMLISTING>extern cyg_handle_t cyg_libc_main_thread;</PROGRAMLISTING>
<PARA>Then for example, you can suspend the thread with the line:</PARA>
<PROGRAMLISTING>cyg_thread_suspend( cyg_libc_main_thread );</PROGRAMLISTING>
<PARA>If you call <FUNCTION>cyg_iso_c_start()</FUNCTION> and
do not provide your own <FUNCTION>main()</FUNCTION> function,
the system will provide a <FUNCTION>main()</FUNCTION> for you
which will simply return immediately.</PARA>
<PARA>In the default configuration, <FUNCTION>cyg_iso_c_start()</FUNCTION> is
invoked automatically by the <FUNCTION>cyg_package_start()</FUNCTION> function
in the infrastructure configuration. This means that in the simplest
case, your program can indeed consist of simply:</PARA>
<PROGRAMLISTING>int main( int argc, char *argv[] )
{
printf("Hello eCos\n");
}</PROGRAMLISTING>
<PARA>If you override <FUNCTION>cyg_package_start()</FUNCTION> or <FUNCTION>cyg_start()</FUNCTION>,
or disable the infrastructure configuration option CYGSEM_START_ISO_C_COMPATIBILITY
then you must ensure that you call <FUNCTION>cyg_iso_c_start()</FUNCTION> yourself
if you want to be able to have your program start at the entry point
of <FUNCTION>main()</FUNCTION> automatically.</PARA>
</SECT1>
</CHAPTER>
</PART>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -