T U S W- 5 ( jachun解说优酷 Ja No.5)是什么化学品的缩写

VxWorks / Tornado II FAQ
5. VxWorks Questions
5.1 C++ issues
Q: When I download some C++ code my target crashes, even when I don't
start anything.
A: What is probably happening is any static or global classes that you
have defined are having their constructors called. The class is actually
being instantiated when the file is loaded into memory, thus the
constructor is called.
(From: nick_nw@)
Q: What is the syntax of "taskSpawn" for spawning a method of an object
(C++) as a task.
A: See question .
Q: How can I call a C++ function from within a C-file?
A: See question .
Q: What is the preferred extension for C++ files?
A: For C++-files you can use .C (compared to .c for C-files), .cc, .cpp
or .cxx. Don't use .C (uppercase) as an extension for C++. It works ok on
Unix hosts, but won't work if you develop on Windoze... for obvious
The ending I prefer is .cxx. Certain MS compilers don't like .cc, GCC
doesn't (or at least didn't in the past) like .cpp. Both take .cxx.
(From: engineer_scotty, )
Q: Gotcha with C++ static constructors and GCC 2.95.x (PPC)
A: After several hours of debugging and pulling out my hair :), I've just
found a (afaik undocumented) bug with GCC 2.95.x which may cause static
constructors/destructors to NOT work when loaded onto the target using
the target-based loader (the ld/loadModule) commands. Don't know if this
effects the host-based shell or not.
Essentially, the problem is as follows: The munch script can be told to
produce assembly language output (actually a bunch of __asm__ directives
for the C compiler to swallow) or C output. When the latter is used,
additional flags must be passed to the compiler
(-fdollars-in-identifiers) to get the output
otherwise the presence of $ in the symbols will cause the compile to
fail. For this reason, the Tornado makefiles default to using the -asm
the assembler has no problem with dollar signs.
The munched file, when compiled (by either method) containts two arrays
of function pointers, _ctors and _ these are a NULL-terminated list
of the "constructor functions" and "destructor functions" (functions, one
per file that has static ctors/dtors, which call all the static
ctors/dtors in the file). This seems to work fine with the 2.7.2
toolchain. But with the 2.95. using the assembler rather than
the compiler causes a subtle change in the symbol table entry for the
_ctors and _dtors symbols (one that will NOT only
objdumpppc -t reveals this). The "object" bit, which I suppose didn't
exist with the 2.7 is NOT set when the input to the compiler is
assembly code.
When the output of munch is linked bac everything is
fine until you try loading it on the target. F loadLib
DOES NOT RECOGNIZE _ctors and _dtors as valid symbols and thus does NOT
load them into the symbol table. When cplusCtors is run (either manually,
or automatically if cplusXtorSet is used); it looks in the symbol table
to find _ assumes that the module has no
constructors, and silently exits. (The same applies for cplusDtors and
The workaround is to add the line
MUNCH_FLAGS=
to your makefiles. This will force munch to output C code (which must be
compiled with -fdollars-in-identifiers); which will have the "object" bit
set in the generated object file. loadLib will then properly generate
symbol table entries for _ctors and _dtors, and all will be well.
Again, this affects GCC 2.95.x (using DaveK's stuff) on PowerPC. Don't
know about other architectures. The 2.7.2 toolchain that ships with
Tornado also seems to be unaffected.
(From: sj@, Scott Johnson)
5.2 Communication problems
Q: Is there any instance where msgQDelete can be blocking?
A: Yes, as with a lot of create and delete functions in VxWorks,
msgQDelete() will make use of the dynamic memory management
software to release the memory that was claimed for the message queue
data structures (both the kernel's object structure and the buffer for
messages in this case).
Since access to memory partitions is guarded by a mutex (a good idea!),
it is certainly possible that any xxxCreate or xxxDelete routine could
block. You shouldn't be using these functions in high performance blocks
of code - it is generally best to keep your create and delete operations
to initialisation/shutdown regions of the code.
Now, in the case of message queues, an additional step is performed: the
delete function makes sure that it 'holds' all the message slots so if
there are any messages already in the queue they will still be delivered
(and your task that is trying to delete the message queue will block
until they are). For most people, that is the desirable behaviour since
it makes sure that no messages are lost...
(From: john_94501@)
5.3 Interrupts
Q: In my BSP there is an intConnect, but no intDisconnect. How can I
disconnect a function from a interrupt?
A: I have attached an "intDisconnect()" routine for PPC that
has served me well for many years. Just include it as an extra object
when you are compiling your kernel. It takes one argument (the interrupt
(From: David Abbott, abbottd@jlab.org)
Q: What does "workQPanic: Kernel work queue overflow" mean?
A: It usually means that one of your Interrupt Service Routines is not
clearing the IRQ status properly, so on exiting the ISR the interrupt
line is still active and it is just called again immediately. If you
can't work out which it might help to try and get a logic analyser to
look at the interrupts that are occurring.
(From: Andrew Johnson, anj@aps.anl.gov)
Q: What does the function "__get_eh_context" do?
A: "__get_eh_context" is an abbreviation for "get exception handler
context". This will be called if you have C++ code, you are executing in
an objects context and you have exception handling enabled. The code uses
the `this' pointer and can setup RTTI (run time type identification) and
other C++ facilities.
You could use only Embedded C++ constructs and you will probably be ok.
Alternatively, don't allocate any objects, even on the stack in your ISR.
Object construction can call malloc and other routines that you shouldn't
use. It will definitely setup an exception context so that if an
exception is thrown, the object can be deleted.
(From: Bill Pringlemeir, spam_account@sympatico.ca)
C++ can be used in ISRs with extreme caution, like having the ISR in a
separate module that you can build using -fno-exceptions and -fno-rtti
and being careful not to construct any objects and watching out for
temporaries caused by reference parameters and so on, but there are so
many pitfalls that my advice would be to always write such lowlevel code
as ISRs and even the lower layers of device drivers in plain C.
(From: Dave Korn)
Q: After calling intlock it seems that the interrupts are not locked when
looking at the interrupt control register.
A: Seems that people still do not understand the scope of intLock(). It
works only for the task context that calls it. If that task blocks (or
exits), then interrupts will most probably be re-enabled. If the task
only blocked, when it resumes execution they will be locked again.
Why? Because the MSR (using PPC) is in the task context. You should not
block with interrupts locked (or, for that matter, after calling
taskLock() either). Switching to a different task, or the idle loop, will
re-enable the interrupts.
As for the wind shell (host shell), when you execute a command there,
the target agent spawns a task to call the function. So calling intLock()
from the wind shell results in a task on the target executing intLock()
and exiting. When the task exits, the scheduler will be invoked and when
the new task is selected, its value for the MSR will be restored.
(From: John, john_)
(Note: this is also the case on MIPS. Also when calling intEnable on
MIPS the interrupt will only be enabled for the task where you called
intE Johan)
5.4 LoadModule problems
Q: When I try to load a module with unresolved externals the function
loadModule returns a module-ID instead of returning NULL, as described in
the manual. How do I detect if there are unresolved externals?
A: First set errno to 0, then execute the call to loadModule, and if this
call returns a valid module-ID check errno again. If errno indicates an
error there probably were some unresolved externals. In this case it is
better to unload the module again.
(From : Bob Marino, ram@)
Q: The ld command, run from a script, is behaving differently on a UNIX
and an NT box.
A: I've observed a difference with the behavior of startup scripts. The
ld command's normal form:
worked fine with a UNIX host, but failed on NT. I eventually found that
the terminating &CR& was being included in the file name read from
the script and passed back to the ftp server. The workaround was to use
an alternate form of the ld command in startup scripts:
ld 1,0,"foo"
This works fine with both UNIX and NT hosts.
(From: Jerry Hudgins, jerry@)
5.4A malloc and other memory issues
Note: this section is added later, but to keep the order right and not
have to renumber all sections I added it as 4A.
for information about
memory leak detection
Q: The VxWorks port of an alternative code for dynamic memory allocation,
made by Doug Lea.
A: This post provides details of getting Doug Lea's allocator (dlalloc) to
work with vxWorks 5.4 (possibly 5.5).
These posts are based on version 2.7.2 of the allocator.
There are three files.
This attempts to extract memLib.o and memPartLib.o from the vxWorks
It deletes symbols that are replicated in the DL
allocator.
configures the allocator for use with vxWorks.
Most changes are at
the start and end.
tried to minimize changes.
Added vxMemInit().
After extracting the memLib.o and memPartLib.o, these must be added to the
build as extra object files.
The file "malloc.mk" is never used again
unless you wish to generate these files each time you build.
might insert the rules directly into your vxWorks makefile or project.
The malloc.c files should be compiled and linked before any libraries.
This will enhance performance on system that make extensive use of C++
and objects.
(From: Bill Pringlemeir)
Q: One of my tasks in getting suspended all the time, in memPartFree.
What is causing this?
A: In vxWorks land, freeing same memory location twice will suspend the
task which has called free() second time. This will cause exception
similar to one above suspending the task.
The way to fix this is by making sure you don't free memory twice.
(From: Narendra Hadke, )
5.5 pthreads
Q: Has anyone ported pthreads.h from Linux to VxWorks?
A: Yeah, we've done that. The mapping from pthreads to VxWorks task_* et
al. is pretty straightforward. The only thing missing is condition
variables. They turned out to be kind of hard. You might also be able to
use VxWorks semaphores, but we took a different approach. We used a msgQ
and taskSuspend()/taskResume(). See this file for the implementation:
The rest of the implementation is very easy, so I won't bore you with
the details.
(From: Craig Vanderborgh, )
Q: Is there a way to implement the VxWorks API on top of pthreads, to
simulate VxWorks on a different system?
A: Check out
they've recently published a white paper that discusses this and the
problems and differences between the two APIs.
(From: Andrew Johnson, anj@aps.anl.gov)
5.6 Reboot
Q: When I do a hard reboot the system reacts differently than when using
Ctrl-X. The reason is that Ctrl-X does a reboot(0), while a hard reboot
does a reboot(2), a boot clear. How can I let Ctrl-X do a reboot(2)?
A: Unfortunately, the ^x functionality is hardwired to do a "reboot
(BOOT_WARM_AUTOBOOT)" call when the reboot character is recognized. There
isn't any way to change what type of reboot is done. Some possible ways
around this (none pretty) are to:
Change the sysToMonitor function that gets called as the last step of a
reboot to override the "start type" used. This function is normally
provided in sysLib.c as part of your BSP.
Use the abort function capability of the terminal driver to do the type
of reboot you want. The abort function is normally tied to ^C and is
used to restart the "shell". If you can live without that capability,
you could use tyAbortSet() to change the abort character to ^X and use
tyAbortFuncSet() to install a function that would do the proper type of
reboot (i.e. call reboot(BOOT_COLD)). You would need to make sure
OPT_ABORT option was enabled for the serial connection.
Install your own "reboot" handler that "took over" and finished the
reboot process. You could use rebootHookAdd() to put in a function that
did what reboot does. As I remember from when I decoded the routine it
did some cache disabling and then called sysToMonitor() with the "start
type" parameter. You could do those same things
calling sysToMonitor(BOOT_COLD).
The first option is the easiest by far.
(From: Fred Roeber, )
5.7 Semaphores
Q: It looks like the priority inversion mechanism is not working
correctly.
A: This may not be the issue here, but you should note the throw-away
line in the semMLib description:
"The task will return to its normal priority only after relinquishing all
of its mutual-exclusion semaphores that have the inversion-safety option
So if your Task Two happens to have hold of some other (probably
unrelated) inversion-safe mutex, this will prevent it from reverting to
its former priority, even though Task One is not waiting on the semaphore
you are currently focussing on. (This was the cause of a deadlock I
recently encountered!)
(From: Will Fookes, will@noSpam.wfookes.co.uk)
5.8 Simulator (VxSim)
Q: How can I start multiple simulators on NT and have these
communicating?
A: While in a VxWorks class, the instructor gave me the following info.
With this I was able to finally get it to work!
Just two things:
Make sure you configure WDB END driver instead of the WDB simulator
development tool components -& WDB agent components -&
select WDB connection -& WDB END driver connection
I got an exception using buffers greater then 1400 with a TCP
connection. Fragmentation problem? Same code works fine on real
The info in in .
(From: Luc Pariseau, )
Q: How do I increase the memory of the simulator?
A: Use the /r switch to control the amount of memory of the simulator.
The size is in bytes, and not in kBytes as the manual states. You also
have to build a custom-configured simulator, as the default simulator
does not support the /r-switch.
In case the command line is not an option, here is
another way: I think the magic line you want to change is in
01Simulator.win32.tcl: [::simulatorLaunch $imageName $pNo $workingDir
30000] \ and the 30000 will be your memory size. If you don't want to
brute force it you can add code to the showImageDlg procedure (look at
the dialog on the bottom of the file) to prompt you for it. Right now it
seems as if it's hardcoded on win32 platform and they prompt you only on
UNIX.. (look in the Launch directory for the UNIX implementation)
(From: Steven Szabo, Steven.)
Q: How can I have 2 simulators communicate with eachother on Win2K box?
A: You need to setup the ULIP driver correctly, which means you need to
enable IP-Routing.
Here is the result of my "ipconfig /all" (Sorry, output is in German!
(Ja means Yes, Nein means No)):
Windows 2000-IP-Konfiguration
Hostname. . . . . . . . . . . . . : martin
Primares DNS-Suffix . . . . . . . :
Knotentyp . . . . . . . . . . . . : Hybridadapter
IP-Routing aktiviert. . . . . . . : Ja
&-------------------
WINS-Proxy aktiviert. . . . . . . : Nein
Ethernetadapter "vxSIM WindRiver":
Verbindungsspezifisches DNS-Suffix:
Beschreibung. . . . . . . . . . . : WindRiver ULIP
Physikalische Adresse . . . . . . : 00-00-00-00-00-00
DHCP-aktiviert. . . . . . . . . . : Nein
IP-Adresse. . . . . . . . . . . . : 90.0.0.254
&--------------------
Subnetzmaske. . . . . . . . . . . : 255.255.0.0
&-------------------
Standardgateway . . . . . . . . . :
DNS-Server. . . . . . . . . . . . :
Pinging from one to the other vxSim works fine. But you need to start the
Simulator using a processor number &0, then you will get the target
server calling parameters to start with wdbrpc: 90.0.0.2 -B wdbrpc
-Bt 3 -R f:\TEMP\tsfs -RW -n "vxsim1@martin"
Here is my output:
Simulator #1 to #3:
-& ping "90.0.0.4"
PING 90.0.0.4: 56 data bytes
64 bytes from vxTarget (90.0.0.4): icmp_seq=0. time=0. ms
Simulator #3 to #1:
-& ping "90.0.0.2"
PING 90.0.0.2: 56 data bytes
64 bytes from vxTarget (90.0.0.2): icmp_seq=0. time=0. ms
Simulator #3 to win2k host:
-& ping "90.0.0.254"
PING 90.0.0.254: 56 data bytes
64 bytes from host (90.0.0.254): icmp_seq=0. time=0. ms
(From: Martin Raabe, Martin.)
Q: The font in my VxSim window is very small.
A: You are probably using Regional settings other than English. If you
change it to English, it should work. There is also another way where you
don't have to change regional settings and it involves tempering with the
code of VxWorks.exe.
(From: Tomislav Razov, tomislav.razov@siemens.hr)
It is also possible to use the following tool. The
exe file should be run after each time you run the simulator. We
integrated the call into the resposible TCL file, which is
also. The tool (source and
executable) can be found here: .
(From: Ofer Goren, ofer_)
Q: How can I make 2 simulators communicate on a Solaris box?
A: Enable IP forwarding on solaris.
ndd -set /dev/ip ip_forwarding 1
(From: Vijay Paul, )
5.9 Task related items
Q: What is the use of taskDelay(0)?
A: The following msg was posted by Dave Schmidt of Wind River on the
newsgroup concerning taskDelay (0):
That will put the current task at the end of the ready queue for the
current priority. It will allow any other tasks on the ready queue of the
same priority to be run (sort of round robin, if you issue taskDelay(0)
for them also when you want to go to the next task), of course all higher
priority tasks will run and intterrupt service routines will also run.
Please note that this method will NOT allow tasks of lower priority to
run, it just forces a rescheduling. If the task being delayed is the only
one of that priority, then it will restart immediately.
Q: How do I use taskInit?
A: First: why use taskInit? If you want to synchronise startup use
taskInit and let the new task(s) wait on a semaphore.
But if you still want to use it, here are some examples:
From john_94501@:
This code is cut from something that uses taskInit in a portable way
(i.e. it takes into account the stack direction of the CPU being used).
This is another reason why I prefer to use taskSpawn!
/* initialize TCB and stack space */
memArea = (char *) malloc (STACK_ROUND_UP(STACK_SIZE) + sizeof (WIND_TCB) + 16);
/* initialize task */
ret = taskInit ((WIND_TCB *) (memArea + 16), NULL, 150, VX_NO_STACK_FILL,
#if (_STACK_DIR == _STACK_GROWS_DOWN)
(char *) (memArea + STACK_SIZE + sizeof (WIND_TCB)),
memArea + STACK_ROUND_UP (sizeof (WIND_TCB) + 16),
STACK_SIZE, (FUNCPTR) function,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
/* args */
if (ret == ERROR)
perror ("taskInit");
return(0);
taskActivate ((int) memArea);
And that is basically it! Your task should be running by the end of that
sequence. If you wish to delay the starting point just move the call to
taskActivate().
Another example from steven.offenbacher@jhuapl.edu:
I also have a working example where I don't use malloc. I statically
create the TCB and stack.
WIND_TCB tMonitorT
char tMonitorStack[STACK_SIZE];
Example #04.
taskInit/taskActivate method using statically allocated
TCB and stack
status = taskInit(&tMonitorTcb,
/* TCB Address
"tMonitorMethod04",
/* Task/Thread Name
/* Priority 0=Highest */
VX_NO_STACK_FILL,
/* Options
Determine which way stack grows and
adjust address if necessary
#if (_STACK_DIR == _STACK_GROWS_DOWN)
tMonitorStack+STACK_SIZE,
/* Stack base address */
tMontiorStack,
/* Stack base address */
STACK_SIZE,
/* Stack size in bytes*/
(FUNCPTR) monitor,
/* Task entry point
0, 0, 0, 0, 0, 0, 0, 0, 0 ,0);
/* VxW Req 10 parms
Task exists but is not running at this point.
The debugger can now attach to the task
and set breakpoints provided the user does not detach or attach to some other task
if (status == OK)
/* Only activate if init ok */
status = taskActivate((int)&tMonitorTcb);/* Actually start task */
Q: When the priority of a task is requested using taskPriorityGet it is
possible that this is not the real value, as this might change due to
priority inversion. How do I get the right value?
A: The normal priority is kept in the TCB. It can be read using this
priority = (taskTcb(taskIdSelf()))-&priN
(From cwein@ and Pete Kockritz, )
Q: Using WindView, I've noticed a task that has just completed (eg. by
returning) doing the following in close sucession:
Calling taskDelete upon itself (presumably this is what should happen
when the task returns)
Being almost immediately preempted by tExcTask, which then:
taskDeletes the task /again/ and then...
calls taskSuspend on the task (which is now *very* much dead)
Why this order, the task would have been deleted after the first call to
taskDelete anyway.
A: The sequence is not only familiar, but it is correct, at least as far
as the deletion of the task... let me explain in more detail...
Normally, when one task deletes another the one doing the work has a
context, stack etc to execute the task deletion code on. This is
necessary, obviously, since the code performing the deletion is simply C
code, and might block or be interrupted.
Now, when a task deletes itself it has a small problem: it can't delete
its own stack and context information (TCB), since that would leave the
executing code without any stack or context. OK, it could lock interrupts
until it was all cleaned up, but that would not be good in a real time OS
where interrupt latency is an important factor.
So, the taskDelete() code performs some checks up front, and if it is
deleting itself the work is actually passed to another task to do
(tExcTask in this case). The actual code is a little more involved, but
this is a rough idea of what happens (function names not accurate, but
chosen to express the concept):
if (taskToDelete == taskIdSelf()
queueJob (taskDelete, taskToDelete);
taskSuspend (0);
Since the exception task is a high priority task it will preempt the task
deleting that was itself in most cases. At some point in the process, the
taskDelete operation blocked for something. At that time, the original
task was rescheduled, and promptly suspended itself (after all, it is
expecting to die very soon...).
Your description sounds pretty much like what I'd expect WindView to see
for a task deletion. The "exception" task is not really that well named
since it is used for more than just displaying exception messages.
Consider it to be a kernel thread, used for the OS to push work out to
task level, much like an ISR that signals an associated task to perform
the actual work.
(From: john_94501@)
Q: How can I build a stack-trace?
A: You can do this using an undocumented function called "trcStack". Here
is all you need. You can even call xxxTrace(tid) from interrupt level...
though logMsg() is far from ideal.
/*******************************************************************************
* xxxTracePrint - stack trace print function
* RETURNS: OK or ERROR
static void xxxTracePrint
INSTR *caller,
int nargs,
char buf [250];
int len = 0;
len += sprintf (&buf [len], "%#10x: %#10x (", (int)caller, func);
for (ix = 0; ix & ix++)
if (ix != 0)
len += sprintf (&buf [len], ", ");
len += sprintf (&buf [len], "%#x", args [ix]);
len += sprintf (&buf [len], ")\n");
logMsg (buf);
/*******************************************************************************
* xxxTrace - stack trace
* RETURNS: OK or ERROR
int xxxTrace
WIND_TCB *pTcb
if (pTcb == NULL)
return (ERROR);
taskRegsGet ((int)pTcb, &regs);
trcStack (&regs, (FUNCPTR) xxxTracePrint, (int)pTcb);
return (OK);
(From: Geoffrey Espin, )
Q: What is the syntax of "taskSpawn" for spawning a method of an object
(C++) as a task.
A: I use the following code snippets to spawn a method as a task. Dont
forget the '(int)this' for the first parameter.
//start sampling data count and timestamp
timeCodeGather =
tid = taskSpawn("tTimestamp", 250, 0, 20000,
(FUNCPTR)TimeStamp::addNewTimeStamp,
(int)this, 0, 0, 0, 0, 0, 0, 0, 0, 0);
void TimeStamp::stopTimeCodeGatheringTask()
//## begin TimeStamp::stopTimeCodeGatheringTask%.body preserve=yes
char tmpbuf[20];
if (timeCodeGather)
//stop timecode gathering task
taskDelete(tid);
From: Bob, )
Q: How can I detect a stack overflow?
A: In the past I used the next code (typically for x86 targets):
int switchHandler(WIND_TCB *pOldTcb, WIND_TCB *pNewTcb)
if ((pOldTcb-&regs.esp & (ULONG)pOldTcb-&pStackLimit) ||
(!(pOldTcb-&options & VX_NO_STACK_FILL) &&
((int)*(int *)(pOldTcb-&pStackLimit) != 0xeeeeeeee)))
logMsg("Stack overflow task 0x%08x\n", (int)pOldTcb,0,0,0,0,0);
taskSuspend((int)pOldTcb);
/* __asm__("int $12"); */
int start_application(void)
/* Enable kind of dynamic stack checking */
if (taskSwitchHookAdd(switchHandler) == ERROR)
printf("taskSwitchHookAdd error\n");
return ERROR;
(From: Gerald van Kampen, kam@oce.nl)
Q: I want to block a task until all children are in a certain state
(initialised, finished, etc.).
A: This can be done using semaphores:
* Global semaphore used by each terminating child CSP task.
SEM_ID childF
* A child task.
void child (void)
/* Normal child like activities. */
semGive (childFinished);
NUM_CHILDREN
* Parent task.
void parent (void)
int childCount = 0;
* Use a FIFO if you are more interested in speed than the order that
* tasks will be blocked in.
if ((childFinished = semCCreate (SEM_Q_FIFO, NUM_CHILDREN)) == NULL)
/* We're not in the mood for creating children :-( */
/* Spawn children,-) */
/* Wait for all the children to complete their chores */
semTake (childFinished, WAIT_FOREVER);
} while (++childCount & NUM_CHILDREN);
/* Tidy up after children (usual parental type stuff) */
semDelete (childFinshed);
(From: Alex Goodyear, spamless.agood@jet.uk)
Q: What are +T, +I thingies in the "i" output?
The following is an excellent description of all these symbols by many
people on the net, including "Fred J. Roeber" and others:
Description
Status symbol
=====================================
===============
and task's priority inherited
Delayed and suspended
Pended and suspended
Pended and Delayed
Pended, delayed and suspended
The DELAY state indicates that the task has done some sort of delayed
call while PEND means the task has done something that caused it to
block like trying to semTake a semaphore someone else was holding.
PEND+T means that the task is both
it has done a
semTake with a timeout. +I means that the task has (temporarily)
inherited a higher priority through the use of a mutex semaphore.
The priority inheritance protocol also accounts for the ownership of
more than one mutual exclusion semaphore at a given time.
such a situation will execute at the priority of the highest priority
task blocked on any of the owned resources.
The task will return to
its normal, or standard, priority only after relinquishing all of the
mutual exclusion semaphores with the inversion safety option enabled.
If you use nested mutex semaphores with priority inheritance turned on then
when a task inherits a high priority due to some inner semaphore it owns,
it doesn't lose that priority until it relinquishes all the semaphores it
This doesn't quite follow the rules for priority inheritance (to
the extent that there really are any rules) in that normally, a task's
inherited priority should decrease as it releases each nested semaphore to
whatever the priority ceiling is for the semaphores it still holds.
Getting this incremental priority reduction to work right in practice,
though, is extremely difficult (some of the SUN papers on the Solaris real
time scheduling indicate that this was one of the hardest things for SUN to
get right in their OS upgrades).
Given that VxWorks is a real time
embedded OS, I, for one, don't care if WRS uses the current implementation
even though it isn't "pure" because the result is a more reliable
implementation that runs more deterministically.
Anyway, my guess is that
you will find that you have some nested semaphore code where you are doing
something after releasing one of the nested semaphores that shouldn't be
done at a high priority.
(From the old FAQ)
5.10 Time related items
Q: I would like to know how to measure the system time at a specific
moment, then at another moment, only a few milliseconds later, to
determine elapsed time.
I have tried clock_gettime(), but this is no good. I have checked the
clock resolution and it is at 60 ticks per second.
A: The following was written by Fred Roeber () in the
newsgroup:
The easiest/best way to measure detailed elapsed time is to use any
"timestamp" driver that may be supplied as part of your board's BSP. The
timestamp driver is a generic name for a high resolution timing factility
that is intended for WindView use but can also be used by user
applications. The documentation for creating/using the timestamp facility
is in Appendix G of the WindView manual and the functions are defined in
h/drv/timer/timerDev.h (see sysTimestamp...).
Many BSPs come with timestamp driver support even if you don't buy
WindView. You can add the configuration option INCLUDE_TIMESTAMP to build
it into your system. You can then call sysTimestampEnable to start it up
and sysTimestampLock to read detailed time values. You can call
sysTimestampPeriod to find out how often the timer rolls over and
sysTimestampFreq to see the rate it ticks at (which is often fast enough
to provide microsecond resolution).
The reason I prefer this approach to cranking up the clock rate is that
you typically get much higher resolution values without bogging down the
system with all the overhead of frequent timer interrupts.
As with most things in VxWorks, caveats are needed in applying a generic
facility to specific boards. First, not all boards have timestamp driver
support. Second, on those that do, the timestamp sometimes has a pretty
small period (it rolls over frequently). For instance, on the PPC
platform, the "standard" timestamp driver derives the timestamps from the
decrementer timer which is also used for the system clock. This means the
time value rolls over at the rate t making it pretty
useless for measuring things with a long duration.
There is an alternative timer for some PPC boards that uses the Z8536
chip. The other day, we needed to time startup code on our Radstone PPC
board and I found that with a little work the PPC timestamp functions fit
the bill nicely. The ppcZ8536Timer.c can be rewritten such that it only
provides auxilliary clock and timestamp support (with no system clock
support - that comes from ppcDecTimer.c). By using the 16 bit timers 1
and 2 in "linked" mode it was possible to get a nice 32 bit timer that
rolled over every 20 minutes in our case. We left timer 3 on the chip for
auxilliary clock support. The original timestamp functionality in the
driver was, unfortunately, fairly well broken but not unsalvageable. Just
trying to point out that in some (all?) cases you have to be careful when
using VxWorks drivers.
Caveats aside, people should really consider the timestamp routines. They
can often provide good timing insight with minimum trouble. Fred
Q: When I create a timer function my program crashes after the time
specified instead of executing the function I specified. What is
happening?
A: One thing to watch out for (it got me) is that your handler for the
timer is executed IN THE CONTEXT OF THE TASK THAT CREATED IT. If the
timer was created by some startup task which has since died and gone
away, then this will quite likely crash your system the first time that
the timer callback function is activated!
(From: Will Fookes, will@noSpam.wfookes.co.uk)
Q: How do I determine the number of ticks remaining in a watchdog timer?
A: I got this code from my FAE a few years ago. You will have to search
for what you need to include for the state #defines and the OBJ_VERIFY()
typedef struct
/* OUT_OF_Q, IN_Q, DEAD */
} WD_INFO, *pWD_INFO;
STATUS wdGetInfo ( WDOG_ID wdId, pWD_INFO wdInf )
/* LOCK INTERRUPTS */
lock = intLock ();
/*Verify watchdog ID */
if (OBJ_VERIFY (wdId, wdClassId) != OK)
/* UNLOCK INTERRUPTS */
intUNLOCK (lock);
return ERROR;
/* record state */
state = (int) wdId-&
/*If not in queue then ticks are zero*/
if (state == WDOG_IN_Q)
ticks = Q_KEY (&tickQHead, &wdId-&tickNode, 1);
//ticks = 0;
ticks = 0;
/* UNLOCK INTERRUPTS */
intUNLOCK (lock);
/* fill structure */
wdInf-&Ticks =
wdInf-&State = state & 0x3;
return OK;
(From: Bruce, .invalid)
Q: Errors in the time modules.
A: taskDelay(-1) shows another bug in the vxWorks timer/tick code. It has
the (side) effect of setting vxTicks to zero. This corrupts the localtime
(and probably other things).
In fact taskDelay(x) will have the same effect if vxTicks + x &=
If the system clock rate is 100Hz this happens after about 500 days
(because vxTicks wraps). At faster clock rates it will happen sooner.
Anyone trying for several years uptime?
Oh there is an undocumented upper limit on the clock rate. At rates above
4294 select() will fail to convert its 'usec' time into the correct
number of ticks.
(From: David Laight, dsl@tadpole.co.uk)
Q: How can I create a repeat with a small delay without using
busy-waiting?
A: The reason for not using busy-waiting is to allow other tasks to make
use of the spare CPU cycles. But you must remember that context switching
is quite a slow operation. Two task-swaps every 20usec for 1ms.means 100
task swaps per millisecond which works out equivalent to a task-switching
tick rate of 100 kHz. Which would undoubtedly bog down the CPU pretty
badly, and so not produce the desired saving, to put it mildly...
The 'correct' way to achieve this goal is to use an interrupt driven off
a hardware timer. Do it something like this:
In the driver function:
Set timer: delay = 20 usec, repeated count-downs, trigger an
interrupt each time it hits zero.
Wait for the interrupt to finish by sleeping on a
previously-allocated binary semaphore.
In the interrupt that is attached to the hardware timer
Do your business.
Decrement the count.
If there's more business to do (count non-zero) reset the timer to
interrupt in another 20 usec, else halt the timer and semGive the
semaphore that the foreground is waiting on.
This solution then has the advantage that a) the 20usec. intervals are
accurately timed by hardware rather than approximated by delay loops that
will themselves be subject to interrupts and b) any spare CPU cycles are
given to another task, but the task that has called into the driver only
gets put to sleep once and woken up once.
Note that as described above, there will be a wasted 20usec delay at the
start while waiting for the timer to first count down. You could perhaps
do the first time from the foreground driver code at the same time as you
set the timer going. Perfection is left as an exercise for the reader :-)
(From: Dave Korn)
Q: How can I monitor the processor-load?
A: The code we use for CPU monitoring is
I've probably missed the odd definition from earlier in the file but I
think they should be pretty self-explanatory. It creates a task at
priority 255 = idle task level, which eats CPU and times itself. The
routine getCpu() returns a doube which is CPU loading as a
%. You have to run the initialise function at a high priority so it gets
its autocalibration done properly.
(From: Andrew Johnson, anj@aps.anl.gov)
Another example.
Based on a discussion about this subject that I read here a few weeks
ago, I wrote
idle time monitor that I
have been testing. It seems to work very well.
You can add it to you build, then start it with nothing running
-& startCPUIdleMonitor
then spawn the task that prints the CPU Idle Time
-& period 10, getCPUIdlefloat
You will need to adjust the ZERO_LOAD_IDLE_COUNTER for your CPU. For my
50Mhz 860T it is around 377000
(From: RonnoBonno, )
Q: Can you give an example on how to use timers?
A: Take a look at
code. It should work
without modifications.
(From: Michel Hendriks, m.hendriksNOSPAM@pijnenburg.nl)
Q: I noticed a rollover in the SNMP variable sysUpTime after around 2,5
A: This can be fixed by editing snmpSystem.h which is supplied as source
with WindNet, and calculating sysUpTime yourself rather than relying on
the value from m2SysGroupInfoGet().
(From: Will Fookes, will@noSpam.wfookes.co.uk)
Q: When a timer expires, the connected routine will execute in which task
A: The POSIX timer will execute in task context, same task that created
the timer using POSIX signal mechanism, and you can taskLock() from
In contrast Wind WatchDog (wdLib) will do a similar service, but mor
elight-weight, and will call the handler routing in interrupt context.
(From: Leonid Rosenboim)
Q: What is the difference between the watchdog library of VxWorks and the
Posix watchdog mechanism?
A: The VxWorks watchdog (wdLib) is a software mechanism for many software
modules to share a single hardware timer, that is the system clock. Each
wdLib client can request a timeout which is a multiple of the system
clock tick, and a user defined function (aka callback) is executed within
interrupt service routine of the system clock interrupt.
Being run at ISR, the wdLib delivery callback is very accurate, as it is
not subject to task priority, but the code therein should be kept as
short as possibly, and comply with the limitations of an ISR, i.e. call
only those system functions which are allowed for ISR, and avoid using
floating point arithmetics.
The POSIX timer is an entirely different software mechanism, which uses
the same system clock as its time reference, but uses the POSIX signal
mechanism (versus callback) to deliver the timer alert to the requesting
task, as a result, the signal function which is executed as a result of
the timer expiration runs within the context of the task that requested
the timer originally.
The signal delivery mechanism will be invoked effectively when the
receiving task is scheduled, which is subject to that task's priority, so
the delivery will be less accurate, and suffer greater delay, but is not
limitted with respect to the length or complexity of code that can be
executed therein. It will only effect the task which is associated with
that timer.
(From: Leonid Rosenboim)
Q: How do I connect a callback to the SNTP server?
A: When starting up, run sntpsConfig, this will connect the sntpsClockHook
STATUS sntpsClockHook(int request, void *buffer)
if (request == SNTPS_ID)
strcpy ((char *)buffer, "pps");
return (OK);
if (request == SNTPS_RESOLUTION)
if (clock_getres (CLOCK_REALTIME, &timeval) == -1)
return (ERROR);
value = timeval.tv_
*((ULONG *)buffer) = (ULONG)
if (request == SNTPS_TIME)
if (clock_gettime (CLOCK_REALTIME, &timeval) == -1)
return (ERROR);
pTime = (ULONG *)
/* Copy number of seconds since 1900 to timestamp. */
*pTime++ = timeval.tv_sec + SNTP_UNIX_OFFSET;
/* Convert nanoseconds to fractional part and copy to timestamp */
*pTime = sntpsNsecToFraction (timeval.tv_nsec);
return (OK);
STATUS sntpsConfig (void)
if (sntpsClockSet ((FUNCPTR)sntpsClockHook) != OK)
return(ERROR);
return(OK);
(From: Jimbob, )
5.11 Wind Web Server related items
Q: When I load a page from this server it takes a lot of time to load all
the items on this page. How can I increase the speed?
A: Use more than 1 HTTP deamon for multiple HTTP request. You were
overloading your HTTP deamon before.
#define HTTP_NR_OF_TASKS
Change this macro in your httpconf.c file.
(From: Computer Engineer, )
Q: A page loads good with Netscape, but IE seems to hang on an applet.
When downloading using a different server everything goes OK.
A: Actually it is the same solution as on the previous question. The
problem is, that IE loads the applets with another socket connection
simultaneously to the rest of the page and since the WindWebServer is by
default single tasked, it locks up. Setting
#define HTTP_NR_OF_TASKS
and the applets load on IE and NS as well.
(From: Andreas Vorgeitz, Andreas.Vorgeitz@)
5.12 Zinc/windML related items
Q: How can I get the current cursor position?
A: The basic idea is to create input queues and attach them to the
Then check the queue for a combination of conditions to see if
the mouse has moved.
Create Input Driver for mouse using either:
ugl8250MsMouseDevCreate - assuming you have a MS serial mouse., or
uglPs2MouseDevCreate.
Here you will specify the queue and interrupt number related to the
mouse and also port address.
call uglInputQEventGet to check for any new events...this can be in a
low priority task.
The elements in the queue will be in a structure of
type UGL_INPUT_EVENT. You need to extract the x,y and 'id' from it.
More details with examples are in the Zinc manual.
(From: Vijay Kumar Peshkar, )
Q: Are there any alternatives to Zinc?
A: There were several discussion a few months back about this. You could
try "" to look for them. Here are some links,
If you want a small gui that works out of the box with vxWorks, then you
can code with WindML itself. This use to be called UGL. It is certainly
capable of making a useful small screen GUI. Many features of Zinc really
aren't needed for many products IMHO. Zinc is nice in allowing GUI
development natively on a workstation or PC.
WindML is your best choice if you don't wish to port things.
Microwindows might be a good choice if you have the time to port things.
(From: Bill Pringlemeir, spam_account@sympatico.ca)
Q: How can I avoid that a combobox blocks input to a editbox?
A: If keyboardGrabId is NULL, then use the winRootGet() member to send
the keys to. While using Zinc 6.0, a combobox on the screen would cause
edit boxes to stop receiving keyboard input.
Using the following patch will solve this.
In WindML 2.0 $(WIND_BASE)/src/ugl/win/winroute.c,
[start patch]
--- winroute2.c Wed Aug 15 14:16:12 2001
+++ winroute.c
Wed Aug 15 14:15:51 2001
@@ -137,6 +137,9 @@
UGL_WINDOW_ID keyboardGrabId = winKeyboardGrabGet (eventRouterId);
if (keyboardGrabId == UGL_NULL_ID)
keyboardGrabId = winRootGet (eventRouterId);
if (keyboardGrabId != UGL_NULL_ID)
pInputEvent-&header.objectId = keyboardGrabId;
[end patch]
(From: Bill Pringlemeir, spam_account@sympatico.ca)
Q: How can I save and restore the contents of the screen?
A: This works for me [change SCREEN_BASE define to match your video
#include &VxWorks.h&
#include &config.h&
#include &stdlib.h&
#include &stdio.h&
#include &stddef.h&
#include &string.h&
#define SCREEN_BASE 0xc0000000
#define WIDTH 640
#define HEIGHT 480
void screenDump(unsigned char *name)
if(name == NULL || name[0] == 0)
name = "screen.out";
fp = fopen(name,"w+");
fwrite((char*)SCREEN_BASE, sizeof(char),WIDTH*HEIGHT*4,fp);
fclose(fp);
void screenPump(unsigned char *name)
if(name == NULL || name[0] == 0)
name = "screen.out";
fp = fopen(name,"r");
fread((char*)SCREEN_BASE, sizeof(char),WIDTH*HEIGHT*4,fp);
fclose(fp);
I call these from the shell.
(From: Bill Pringlemeir, spam_account@sympatico.ca)
Q: How can I use a telephone-like keypad to enter alphanumerics?
A: For the most part WRS/Zinc seem to assume an `embedded PC' with 101
keyboard, mouse and VGA.
I had the same problem and concluded that the Zinc layer was the best
place to do this. I have some experience with hand helds, PDA and have
used different cell phones. The best way is to enable the `key value'
cycling when you are in the ZafFormatString class/gui element. The format
string specifies whether the keyboard entry is going to be numeric,
alpha, alphanumeric, etc. I have modified the file
"src/zinc/generic/i_fmtstr.cpp"; specifically the Event() functions
(especially E_KEY case (i hope you guessed that)).
case E_KEY:
static const char special[30] =
'$', '%', '.', ',', '?', '!',
'+', '-', '*', '=', '^', '#',
[snip, pressing zero several times allows punctuation.]
static const char decode[10][8] = {
{'0', ' ', '~'},
{'1', 'q', 'z', 'Q', 'Z'},
{'2', 'a', 'b', 'c', 'A', 'B', 'C'},
[snip, describes cycling sequence]
// Search for legal characters.
ZafIChar tChar = event.key.
bool stepForward =
/* move cursor forward */
// If special key, overwrite previous value (space).
if('~' == lastKeyValue)
for(int i = 0; i & sizeof(special); i++)
// Check to see if we should not repeat a value.
if(tChar != lastKeyValue)
if(D_ON == zKeyTimer-&Event(ZafEventStruct(D_STATE)))
zKeyTimer-&Event(ZafEventStruct(D_OFF));
MoveCursor(L_RIGHT);
OK, this is somewhat ugly. I did this under time pressure as always. Run
through the `decode' array and look for two possible characters from
IsLegalChar() virtual (or callback) function. If two are found and then
we cycle through the values. Don't move the cursor forward and set a
timer to move the cursor when that happens... ]
// Cycle through keys.
if(tChar &= '0' && tChar &= '9')
const char *p = &decode[tChar - '0'][0];
int i = curKeyI
if(IsLegalChar(p[i], cursor))
tChar = p[i];
// multiple key values for this key?
for(int j = i + 1; i != j = (j+1) %8)
if(IsLegalChar(p[j], cursor))
stepForward =
curKeyIndex =
lastCursor =
i = (i+1) % 8;
} while(i != curKeyIndex);
if(tChar == '~')
[snip, if zero is pressed several times bring up the ZafStringEditor
class. I have totatlly re-written this as well...]
ZafStringEditor *stringEditor = new ZafStringE
stringEditor-&SetRequestor(this);
else if (IsLegalChar(tChar, cursor))
ZafEventStruct tEvent =
tEvent.key.value = tC
ZafUpdateType updateType = stringData-&Update();
stringData-&SetUpdate(ZAF_UPDATE_NONE);
stringData-&Replace(cursor, 1, &tChar, 1);
stringData-&SetUpdate(updateType);
[only move forward if this is no possible cycling...]
if(stepForward)
MoveCursor(L_RIGHT);
// Reset cycle code.
lastKeyValue = 0;
curKeyIndex = 0;
// Restart timer...
zKeyTimer-&Event(ZafEventStruct(D_INITIALIZE));
zKeyTimer-&Event(ZafEventStruct(D_ON));
You must modify this for your application. I suggest that you get
together with someone who knows your market and customize the UI to best
fit your customers needs. This could be a key (*bad pun*) part of the
product. Depending on your market, you may need some characters like
"accente` gui`" [excuse my French] or other odd characters.
One strength of Zinc is that you can over-ride the behaviour of a class
to fit your UI especially over plan vanilla WindML. A
weakness is the resource overhead.
(From: Bill Pringlemeir, spam_account@sympatico.ca)
OpenGL programs running under VxWorks
I've written a layer between UGL/WindML and Mesa so now one can run
OpenGL applications on VxWorks 5.4/UGL 2.0. This layer opens the doors of
the embedded systems space to 3D graphics.
I've been inspired by xmesa sources thus I've used a similar design I've
also ported some demos to WindML from GLUT for testing.
Wind River Systems gave his consent to release my work under MIT
Thus many students and companies will be able to use Mesa on
The code is available for download from:
(From: Stephane Raimbault, stephane.raimbault@deesse.univ-lemans.fr)
5.13 Other items
Q: How can I decode the error numbers?
A: VxWorks errnos are divided into two parts. The high 16 bits specify a
module number in which the error occurred, and the low 16 bits contain
the module-specific error code.
To identify the module, look in $WIND_BASE/target/h/vwModNum.h. The
beginning of the list looks like this:
/* module numbers - DO NOT CHANGE NUMBERS! Add or delete only! */
#define M_errno
(0 && 16) /* THIS MUST BE ZERO! */
#define M_kernel
#define M_taskLib
#define M_dbgLib
So for example if the errno is 0x320001, we look for module 50 (0x32 =
50) and find:
#define M_hostLib
(50 && 16)
So the error occurred in hostLib.
The header file for hostLib is of
course hostLib.h, so we look there for the hostLib-specific error codes,
/* status messages */
#define S_hostLib_UNKNOWN_HOST
(M_hostLib | 1)
So error code 0x320001 is an Unknown Host error from hostLib!
(From: Dave Korn)
Q: How can I have a task that causes an (bus)error to continue after this
A: Take a look at this demo-code: .
(From: Albert H Chen, )
Q: How can I use compression in my application?
A: You can use the inflateLib as it is provided with VxWorks. Another
possibility is to use zLib. Get the source from
It should compile easily for vxWorks. This package is more flexible as
you can handle gzip files.
# makefile.
= ?? Your CPU ??
EXTRA_DEFINE
= -Wcomment
MKDIR = mkdir
TGT_DIR = $(WIND_BASE)/target
adler32.o compress.o crc32.o deflate.o gzio.o infblock.o infcodes.o \
inffast.o inflate.o inftrees.o infutil.o trees.o uncompr.o zutil.o
all : ($OBJS)
include $(TGT_DIR)/h/make/defs.bsp
include $(TGT_DIR)/h/make/make.$(CPU)$(TOOL)
include $(TGT_DIR)/h/make/defs.$(WIND_HOST_TYPE)
## Allow C++ sytle comments (tell Pre-processor).
ADDED_CFLAGS += -Wp,-lang-c
ADDED_CFLAGS += -DVXWORKS=1
ADDED_CFLAGS += -Wall -Winline -O2 -fomit-frame-pointer -fno-strength-reduce
ADDED_CFLAGS += -DNO_DEFLATE=1
The functions in gzio.o are nice. I don't think you have to modify any of
the source.
(From: Bill Pringlemeir, spam_account@sympatico.ca)
I wrote a routine to uncompress an image compressed by deflate. The trick
is that you have to skip the first byte. I think it's a 0x08; it's a tag
that WRS adds to the start of the compressed block. Other than that it
was just a matter of using the zlib routines to decompress it.
I haven't tried to compress an image with anything other than deflate,
but it shouldn't be too hard.
I bet if you asked your FAE nicely, he'd get you the source to deflate
and inflateLib.
(From: , Pete Kockritz)
Q: How can I autostart a loaded module.
A: without changing loader code or implementing an own version of loader:
If you set C++ Constructor to automatic in VxWorks (standard), you might
wrap your application by a static 'startup' class. The creator of the
class may spawn the main task of your application.
(From: Michael Lawnick, Lawnick@softec.de)
Q: How can I check if the memory heap is corrupted?
A: Last week I was hunting down a nasty bug in our software. I finally
found it using a self written function that checks the VxWorks memory
list for errors.
The code is tested on a PPC 750 system, but should work on all systems.
These are the files:
(From: _remove_rene.straub@yetnet.ch, Rene Straub)
Q: How can I get the VxWorks and kernel version?
A: Use something similar to whats in WRS's bootConfig.c
(maybe some others also needed ...)
CPU: %s\n", sysModel());
printf ("VxWorks: %s\n", vxWorksVersion);
printf (" Kernel: %s\n", (char *)kernelVersion());
BSP: " BSP_VERSION BSP_REV "\n");
Creation date: %s, %s using GNU C %d.%d\n",
__DATE__ , __TIME__ , __GNUC__, __GNUC_MINOR__ );
From: Melvin Gardipee "mbgardipee"@.NO_SPAM_)
5.14 VxWorks AE questions
Q: How can I access a fixed address register from within a user level
A: This would work if the code was located in the kernel domain, but
would not be allowed from a user level domain. Probably the simplest way
of getting this to work from user level is to create a small function in
your kernel that does this, make it an entry point and call it from your
application...
(From: John, john_)
Q: How can I spawn an application domain task from a privileged domain?
A: Actually there is a mechanism for this, and better still there is an
example of using it included on every VxWorks AE CD/installation. I know,
because I wrote the VxWorks AE portions of it!
Take a look in target/src/demo/PD and you will find an implementation of
Eliza. This will show you how to create a domain dynamically, attach it
to some code (so you don't even need a loader), and then start a task
running in that new domain.
The call that starts the task is pdRun(). To make it work, somthing must
have registered an init routine for the domain. There are two ways of
doing that:
As in the example, call pdInitRtnSet(). Be careful here: the routine
that you set must be visible in the new domain as well as the current
one - the example uses a shared library for this reason.
Have a function called pdMain() in a module that you load dynamically
into the new domain. The loader will automatically register this
function for you as the domain's init routine. I have used this to run
a multi-process graphical environment under VxWorks AE (part of the
usability tests that we carried out before release).
(From: John, john_)
When I download some C++ code my target crashes, even when I don't
start anything.
What is the syntax of "taskSpawn" for spawning a method of an object
(C++) as a task.
How can I call a C++ function from within a C-file?
What is the preferred extension for C++ files?
Gotcha with C++ static constructors and GCC 2.95.x (PPC)
Is there any instance where msgQDelete can be blocking?
In my BSP there is an intConnect, but no intDisconnect. How can I
disconnect a function from a interrupt?
What does "workQPanic: Kernel work queue overflow" mean?
What does the function "__get_eh_context" do?
After calling intlock it seems that the interrupts are not locked
when looking at the interrupt control register.
When I try to load a module with unresolved externals the function
loadModule returns a module-ID instead of returning NULL, as
described in the manual. How do I detect if there are unresolved
externals?
The ld command, run from a script, is behaving differently on a UNIX
and an NT box.
The VxWorks port of an alternative code for dynamic memory allocation,
made by Doug Lea.
One of my tasks in getting suspended all the time, in memPartFree.
What is causing this?
Has anyone ported pthreads.h from Linux to VxWorks?
Is there a way to implement the VxWorks API on top of pthreads?
When I do a hard reboot the system reacts differently than when using
It looks like the priority inversion mechanism is not working
correctly.
How can I start multiple simulators on NT and have these
communicating?
How do I increase the memory of the simulator?
How can I have 2 simulators communicate with eachother on Win2K box?
The font in my VxSim window is very small.
How can I make 2 simulators communicate on a Solaris box?
What is the use of taskDelay(0)?
How do I use taskInit?
How do I get the real priority of a task?
Question about order of execution for a taskDelete(taskIdSelf).
How can I build a stack-trace?
What is the syntax of "taskSpawn" for spawning a method of an object
(C++) as a task.
How can I detect a stack overflow?
I want to block a task until all children are in a certain state
(initialised, finished, etc.).
What are +T, +I thingies in the "i" output?
I would like to know how to measure the system time at a specific
moment, then at another moment, only a few milliseconds later, to
determine elapsed time.
When I create a timer function my program crashes after the time
specified instead of executing the function I specified. What is
happening?
How do I determine the number of ticks remaining in a watchdog timer?
Errors in the time modules.
How can I create a repeat with a small delay without using
busy-waiting?
How can I monitor the processor-load?
Can you give an example on how to use timers?
Rollover in the SNMP variable sysUpTime after around 2,5 days.
When a timer expires, the connected routine will execute in which
task context?
What is the difference between the watchdog library of VxWorks and
the Posix watchdog mechanism?
How do I connect a callback to the SNTP server?
When I load a page from this server it takes a lot of time to load
all the items on this page. How can I increase the speed?
A page loads good with Netscape, but IE seems to hang on an applet.
How can I get the current cursor position?
Are there any alternatives to Zinc?
How can I avoid that a combobox blocks input to a editbox?
How can I save and restore the contents of the screen?
How can I use a telephone-like keypad to enter alphanumerics?
OpenGL programs running under VxWorks
How can I decode the error numbers?
How can I have a task that causes an (bus)error to continue after
this occurs?
How can I use compression in my application?
How can I autostart a loaded module.
How can I check if the memory heap is corrupted?
How can I get the VxWorks and kernel version?
[AE] How can I access a fixed address register from within a user
level domain?
[AE] How can I spawn an application domain task from a privileged
& J.A. Borkhuis, 2000 - 2005}

我要回帖

更多关于 jachun解说露娜 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信