Let Us Help Make Your World a Little Easier!
by Jennifer C. Sanchez
Marketing Manager & Editor DDC-I Online News
Welcome to the DDC-I Online News January 2004 issue. At DDC-I,
our job is to help you succeed. With a mission and corporate
structure of "#1 in Customer Care", our goal is to offer a
newsletter designed to help make your world a little easier. We
promise to keep this goal in mind with every issue!
New for this year will be a regular column called "Thoughts
from Thorkil" authored by long-time DDC-I A/S employee Thorkil
Rassmussen. Thorkil has worked with DDC-I for over 20 years. He has
substantial experience with all of the DACS tools and is the key
individual involved in all FAA certifications for the DACS product
line. Thorkil's column promises valuable tidbits sure to interest
many readers.
Regular contributions from Linda Rising are also planned. Linda
continues to be a favorite author of our readers. Her articles offer
insightful ways for individuals to improve the way they work and
live.
From time to time we will share a customer story. An impressive
list of large military and aerospace customers around the world are
developing state-of-the-art technologies for very interesting
programs.
Updates from DDC-I and our partners will round out the editorial
calendar. These updates are designed to keep you informed of the
latest news, products, services and technical tips available from
DDC-I and our network of third party partners.
Many thanks to all of our contributing authors. Without all of
you, this newsletter would not be possible.
[
Back to Top ]
DDC-I Offers TADS XTOFF-to-ELF Conversion Tool
Phoenix, AZ. — January 2, 2004 — DDC-I, a leading
provider of multi-language development tools for safety-critical,
real-time developers, today announces the availability of TADS
XTOFF-to-ELF. Capable of converting output from TADS to the
open-standard ELF (Executable and Linkable Format) format with DWARF
(Debugging With Arbitrary Record Format) debug directives, the tool is
another example of DDC-I meeting important customer needs.
"We were helping a customer with a debugging
solution for custom hardware using a proprietary object file format,
in a toolset with the ability to convert an ELF object file into the
format it uses. They needed the ability to convert an XTOFF file,
containing V10DD debug directives, into the non-proprietary ELF format
with DWARF directives," explains DDC-I Senior Software Engineer
Karl Rehmer, lead engineer during tool development.
Creating object files in an object file format called
TOFF, TADS TOFF executables are XTOFF files. The debug information in
a TOFF/XTOFF file is in a proprietary form: V10DD debug directives.
The ELF object file format is a non-proprietary standard for object
files used by a wide variety of products.
Debug information contained in an ELF object file is
typically in directives called DWARF. No attempt to convert V10DD
directives not appearing in the user’s application, or unused by the
customer’s debugger, is made. XTOFF-to-ELF will convert an XTOFF to
ELF, but will translate only the needed subset of the V10DD debug
information into DWARF.
By converting TADS XTOFF files into ELF, object files
generated by the TADS toolset can be used by tools which operate on
ELF files. Operating on any TADS v5.x (or higher) XTOFF file, the tool
currently runs on Windows™ (NT 4.0+, 2000/XP Pro) and converts XTOFF
for the Motorola 68xxx family (68020, 68030, 68040, cpu32) to ELF,
operating with files generated on Solaris or Windows.
According to Rehmer, tool development fell into five
quick phases. After acquisition of a test environment — the
customer's custom hardware — and a debugging solution, project
planning, study of the object file, debug formats involved and high
level design production were to follow. The next three steps involved
successive XTOFF-to-ELF conversions to isolate and analyze source code
variables. A final phase of customer feedback provided input for a
last round of lab-generated improvements.
"The customer was able to begin using the tool
with the first delivery. Once the debug information about variables
was included, they’ve been using it daily with great success,"
concludes TADS Product Champion Harold ‘Bud’ Blum. "Each
phase of the project was completed on or before deadline, proving once
again that DCC-I remains committed to developing our expanding tools
inventory to help our clients excel."
[
Back to Top ]
Thoughts from Thorkil
Endianism: Byte and Bit Numbering
By Thorkil B. Rassmussen
One of the common pitfalls you are likely to
encounter when you move from one target to another is the endianism.
With processors you distinguish between little endian and big
endian processors. Endianism is about byte numbering as well as
bit numbering.
Suppose we have a 32-bit value 0x12345678 (or
16#12345678# in Ada notation), both a little and a big endian
processor will put the proper value in the (possibly aligned) memory
location or register. The trouble comes, if you need to 'tear the
number apart'. You can, of course, get to the individual hexadecimal
digits using arithmetic, such as division by 256 followed by the
modulus of 16, which will yield the value '6', regardless of
endianism. But division may be an inconvenient way of dealing with
the problem.
Processors never really have 32-bit address units,
but rather 8-bit units (bytes), and here is where endianism comes
in. Our 32-bit value has the following bit pattern when viewed in
the normal, left-to-right mode, and where each hexadecimal digit
represents 4 bits:
Bit pattern:
+--------+--------+--------+--------+
| 1 2 | 3 4 | 5 6
| 7 8 |
+--------+--------+--------+--------+
The bytes in the bit pattern are then mapped to memory using the
following overlays:
Little endian: (e.g. 80x86, VAX)
31 24 23 16 15
8 7 0
+--------+--------+--------+--------+
| #3 | #2 |
#1 | #0 |
+--------+--------+--------+--------+
Big endian: (e.g. Sparc, PowerPC)
0 7 8
15 16 23 24 31
+--------+--------+--------+--------+
| #0 | #1 |
#2 | #3 |
+--------+--------+--------+--------+
Looking at the 32-bit bit pattern, overlaying with
an array of bytes (0..3) will on a little endian processor give the
hex value '78'
for array element 0 and hex value '12'
for element 3, whereas a big endian processor will pick up '12'
for array element 0 and '78'
for element 3.
| NOTE: The terms little endian and big endian
refer to which "end" of the number appears first in memory
(i.e., at the lowest byte-address). When the least-significant byte
is placed at the lowest address, the mode is little endian. When the
most-significant byte appears first, the mode is big endian. |
So the code must know which index in the array is
the least significant and which is the most significant. To make the
two cases look the same the four bytes could be swapped in one case
to look like the other, but that must usually be done in a copy of
the four bytes and not in the original.
A general use of this is when the code is reading
four bytes from a stream or a file and wishes to regard this as a
32-bit entity. The code must know in which endian the data was
stored, and its own endian kind. If these are the same the four
bytes may be copied in increasing order to an array of four bytes,
whereas the order must be decreasing, if the endianisms differ.
After the copying, the array may be unchecked converted to a 32-bit
entity, and the value should now be the expected one.
How can you determine the endianism then? Often you
have been doing all your coding on the same processor and have made
your conversions according to the needs of that processor, and may
have detected that a byte swap was necessary to get it to work.
Moving the code to another processor with a different endianism
would then miserably fail, as bytes would be upside down. So it is
important that you detect the executing processor's
endianism, so the proper handling can be adopted, when switching
between representations inside the processor (byte swap or no byte
swap), and when reading information in a different endianism
(straight over or byte swap).
To detect the endianism the following technique may
be used in Ada:
Declare a type being a packed array (0..3) of a
byte type (0..255).
Define a conversion between this packed array
and a 32-bit integer type.
Define an object of the packed array and assign the
value (1,0,0,0).
Define a 32-bit integer object and assign the
conversion of the packed array object.
The processor will be little endian, if the
resulting value is 1, and big endian when the resulting value is 16#01000000# (otherwise).
Concealing the endianism issues in the code to a few
dedicated routines (or better a separate package that will do the
conversions needed), the code should be easily portable from one
processor to the next.
As shown above bit numbering follows the byte
numbering within a multibyte entity. So conversion of a 32-bit
entity into a packed array of 32 Booleans suffers the same endianism
problem like the bytes. The assumption that bit 31 or bit 0 is the
sign bit for instance does not hold, and it may not be the first
thing you look for, when a porting to a new processor fails. Again
you are forced to know which bit number is the least significant -
in little endian this is bit 0, and 31 in big endian. Indexing with
bit number I in little endian will select bit I from the right, and
in big endian this should be (31-I).
For records the representation clause in Ada allows
the definition of the record to choose the little or big endian
representation:
type Rec32 is
record
Least, Less, More, Most : Byte;
end record;
for Rec32 use
record
Least at 0 range 0.. 7;
--
little big: 24..31;
Less at 0 range
8..15; -- little big: 16..23;
More at 0 range 16..23;
--
little big: 8..15;
Most at 0 range 24..31;
--
little big: 0.. 7;
end record;
This of course leads to having different sources,
but in the spirit of encapsulation of the endianism problem,
endianism dependent types and records could be placed in separate
packages that are endian specific, and have conversion routines as
well as required types.
In many cases endianism does not matter - a record
representation clause is perhaps made to pack stuff and not meant to
be converted to another representation anyway, and such records need
not be considered.
In conclusion, it should be noted that it is
important to know, if the source code is indeed endian dependent,
and make the necessary adjustments to make it portable across
processors, using the techniques described above. Of course, care
should be taken to do it right.
 |
About the Author
Thorkil Bjørn Rassmussen has worked with DDC-I for
over 20 years. He has a Master of Science, Computer Science, from
University of Copenhagen. Thorkil has substantial experience with
all of the DACS tools and is the key individual involved in all FAA
certifications for the DACS product line. Thorkil lives with his
wife Jane and two children Jonas and Tine, just outside of
Copenhagen, Denmark. |
[
Back to Top ]
A Tale of Two Successful Projects: Pairing Re-visited
By Linda Rising
risingl@acm.org
www.lindarising.org
Despite all the bad press for our industry, most projects do
succeed and I was lucky because quite recently I conducted
retrospectives for two very successful projects and was able to
capture some information to relate to you. We’re all interested in
doing a better job of development, so let’s see what these
experiences teach us.
You can read more about pair programming and retrospectives in the DDC-I
news archives. I’ll lead you through the steps of
our retrospective activities, so even if you have never been through a
retrospective (or postmortem), you can still understand what happened.
The first was a very small project with two DDC-I employees. This
was their initial experiment with pair programming, so I was anxious
to hear how it worked for them. We began the retrospective with the
following exercise. I asked them to pretend that a colleague had
approached them with the question, "Was your project a
success?" The way this exercise is done is to provide as many
answers as possible of the form, "Yes, it was a success because
<reason>." This is a good exercise to use at the beginning
of a retrospective because it sets the tone for the entire experience.
Many times team members are exhausted at the end of a project and
can only remember the hectic activity in the last stages. Many times,
they can’t even see their own successes and they focus, instead, on
all the things they didn’t have time to address. When they have to
think of good things, they realize how much they were able to
accomplish. Every project has some successes to share. The answers to
this question in this activity make them aware of some of the benefits
that they want to capture for future projects. This is a brainstorming
activity where anyone can contribute something he or she thought was a
good thing about the project. We capture as many of these successful
attributes as possible. Things that didn’t work well are captured in
a later exercise. Here’s the list of "reasons" from this
team.
- The customer was satisfied with the product, not just at the
end, but throughout the project.
- We met all our milestones—on time!
- We were under budget.
- We were lucky! Things worked out for us.
- Pair programming was a success.
- We were agile. Our design evolved. We didn’t waste time
specifying it in detail at the beginning.
- We dealt with issues as they arose and didn’t anticipate
problems that we never faced. We didn’t try to solve problems
without adequate understanding; by the time we really needed to
solve a problem, we had the knowledge we needed.
- We used short delivery cycles, and each deliverable contained
the things that were most important to the customer for that
milestone.
- We kept the customer in the loop; there were no surprises.
- We realized early that the allocation of two half time
developers would not be enough and that at times during the project
one or both of us would have to work full time to meet the schedule.
This early realization helped us plan for these times.
- In our evolving design, we did a good job of encapsulation,
information hiding, and modularity. This led to an improved
modifiability that helped us make the changes we needed as the
product evolved.
- One team member’s in-depth knowledge and experience with the
programming language and some elements of the project.
- We had good documentation to help us understand the format and
meaning of the input to the converter and the format and meaning of
the output of the converter.
- We decided not to physically re-use old code but studied it to
learn its basic flow of control.
- We worked together to adjust our schedules to allow each of us
to work half time but still pair as much as possible.
The next step in the retrospective was to consider my good friend,
Norm Kerth’s [Kerth01], definition of success: "On a successful
project, everyone says, ‘I wish we could do that over again—the
very same way.’" Of course, this is never the case, but the
question helps the participants focus on the things that should be
done differently in future projects. Here’s this team’s list of
things that should be done differently.
- One team member was pulled off early to do other work. This
meant a loss of pair programming opportunities and a heavier burden
on the remaining member of the team. This is a fact of life for most
development, but it always has negative impacts and is something
that no one wants to see.
- Our architecture was documented but there was no high- or
low-level design information for the maintainers who follow us.
- It would have helped to find documentation of the debug
information content needed in the output.
It would be nice if we could just hold a short meeting and simply
answer these two questions, make lists, find solutions, and then move
on. Typically, though, most team members need help to remember the
beginning of the project and re-live the time spent working on the
project to pull out all the things that worked well and the things
that should be done differently. There are many exercises that improve
team memory and the resulting quality of the lists of answers to the
questions. From these lists, a few items can be identified as worth
creating strategies to ensure that good things continue and other
things change.
One exercise that can help team memory is to build a timeline. The
technique I use is to have participants describe the events that
happened—as they saw them—and write them on cards that are posted
on the wall. The cards are color-coded depending on how they felt at
the time of the event: Red = angry or frustrated;
Blue = happy; Green
= challenged; Yellow = surprised. Here are some things I look for.
If there are no red cards, I suspect that the team is afraid to
tell the truth. On the other hand, if the wall is covered in red, that
indicates other serious issues for the team. In this project there
were a few red cards, but nothing extraordinary. If there are a few
surprises and some challenges that means the project was probably fun
and interesting. That was the case here. If there is no blue—especially
at the beginning and at the end—I’m concerned about an
inauspicious start or finish. This project had a lot of blue
throughout—typical for a good team and a good project.
When I asked the team to tell me anything else that might not have
made it to a card, here are some of the things they said:
- Pair programming was great, but the real benefit for us was
"pair understanding." We read the initial set of documents
together. It was like a study group. Neither of us was an expert in
this domain, but we each saw something that helped our collective
understanding. We were able to build on that understanding, step by
step, and create more knowledge than either of us would have been
able to do alone. In fact, we can say with some certainty that the
milestones on this project would not have been met (and certainly
not have been met with the quality we delivered) if we had not used
the pairing techniques.
- It would have been difficult for us to work in the
"old" way—in parallel. The work was a sequence of
development stages and each stage depended on the previous work.
Dividing up the work in this way would have meant that one of us
would have gone ahead without knowledge that he needed and would
probably have made a lot of incorrect assumptions creating
significant re-work. Working as a pair was much more efficient.
- Having the other person say, "What about this?" meant
that we were always forced to consider alternatives and that
produced a better design and a better product. It takes some getting
used to and you have to be open to suggestions from others, but
after awhile we took joint ownership of the product and we each
wanted to make it the best we could. That meant always hearing from
the other member of the pair about a better way.
- The problem in many companies is that domain knowledge resides
in one person’s head. Whenever a task in one of those areas must
be done, then anyone who is not the resident expert will have a
tough time. Having two people learn about new work means that in the
future, we won’t be dependent on just one expert. We will have
two.
After the discussion, we created a list of recommendations for
future projects. Notice that pair programming heads the list.
- Future projects should try pair programming. It’s good to
have another brain for questions and sharing knowledge and
successes.
- Future projects should try to provide a Place of Our Own (it’s
a pattern). Pairing is noisy and it’s good to have a room with a
door to avoid disturbing others.
- When pairing on future projects, be aware that you will have to
adjust your schedules to allow time to work together.
- In future projects, try to set initial expectations with the
customer and continually involve and solicit feedback (not just
status reports).
- Use short delivery cycles (when appropriate) in future
projects.
- In future projects, hold stakeholder meetings at the end of
each short cycle to allow the feedback in #4 above.
- Adopt as many agile practices as appropriate in future
projects.
- In future projects, create a maintenance document. Include
high-level design and suggestions for debugging.
At the end of the retrospective, I asked the team to write some
short statements expressing their hopes and wishes for future projects
at DDC-I. With that, we ended the session and brought in other
developers and managers to walk the timeline and see the posted lists.
Their hopes and wishes for future projects:
- We hope that the ideas and suggestions brought about during
this retrospective are implemented successfully.
- We wish that all projects could involve more than one person to
allow sharing of information.
- We wish that all projects were divided into smaller, more
manageable chunks.
- We hope that feedback from the customer and management
continues to be a frequent occurrence throughout all projects.
The second project was especially interesting because it was part
of the Arizona State University Software Factory: http://sf.asu.edu/
The premise is an intriguing one. The following is from their web
site:
Here, as at other universities, software development is becoming
ever more crucial to research. Researchers typically develop
software by "ad hoc" methods, hiring students to do their
programming. This works out in some cases, but more often than
not the students lack experience in software development and the
faculty lack experience in software engineering. This leads to a
sub-optimal learning experience for the students and poor software
products for the researchers.
The software factory idea, then, is simple: Gather these
part-time student programmers in a common facility, put them under
professional management and mentorship, and use sound software
engineering techniques in the development process. The result:
- Researchers get well-designed, documented, and tested software.
- Students get experience working in a professional software
development organization.
- ASU gets a reliable software development capability that will
enhance bids for research funding.
The part-time student programmers on this project were all graduate
students, with considerable background in programming and software
engineering. You would expect that their work would reflect their
knowledge and experience. Since they are also in a learning
environment (isn’t this what all good companies strive to create?),
you would also expect that they would be up-to-date on the latest and
greatest software engineering practices. In all of these expectations,
I found that I was not disappointed.
The activities from the retrospective were similar to those of the
DDC-I retrospective.
Since this is an on-going project, the team identified three things
that they would like to be sure to continue. These are things that
worked well that they don’t want to forget. Limiting the list to
three things ensures that the team will focus on these and be
successful in actually carrying out their intention. I have seen teams
make unmanageable lists in their enthusiasm, but then find that they
were overwhelmed with the amount of work required to really make
things happen. I’ll provide a bit of explanation for each item.
What worked well that we don’t want to forget as we go forward:
1) Testing:
- automated (This team was practicing XP or extreme programming,
which recommends test first development and automated testing. This
ensures that any changes that are made in refactoring can be verified
quickly and easily. Without automated tests, it can be too cumbersome
to run a large bank of tests, even if the tests are available.)
- test code (Test "code" was written along with the code
to ensure that as features were added, they could be verified.)
2) Work with customer colleague: (Throughout the project the
customer was available to the team – another XP practice. The
availability varied and the team, in retrospect, could see that the
frequency of customer sessions impacted the team. The suggestion is an
"experiment" going forward.)
- 1/week session = good
- 1/month session = not enough
- maybe every 2 weeks
- feedback is important; "Pairing" with customer (Here we
can see the instance of pairing that was significant for this team.
Pair programming is already an accepted practice, no longer really
noteworthy. Pairing with the customer worked well and the team wants
to "remember" that going forward.)
3) iterations (almost) = 1 month (Teams that use short iterations
to produce products incrementally almost always report success. A
series of small development steps usually leads to better products
than a large effort that may or may not yield the desired result.)
What should be done differently? Even the best teams can find some
room for improvement. In a retrospective, as a team takes time to
examine what happened in the latest development cycle, there are
always suggestions for making the team experience better going
forward.
1) More than one person modifying a file: (Yes, there is a CM
tool and process, but adding new features was sometimes problematic.
Since the programmers are students, who work part-time, ownership of
files and features is more difficult to implement. This item
represents an opportunity for experiments with team process going
forward.)
- ownership
- check in/out
- small team size
- more modular approach
2) TDD (Even though the team has adopted the XP practice of
test-driven development, and even though the team could see this as
a desirable practice – it appears on the previous list of things
to continue – it wasn’t applied in 100% of the development.
Steve Gordon is the manager of the Factory and has taken on the
challenge to encourage this across all Factory projects.)
- Steve's Mission
3) "Minimal" up front design: (A practice of XP is to
avoid getting stuck in long up-front planning. Sometimes, however,
all planning is tossed out the window – losing the baby with the
bath water. Most teams recover from this and realize that some
"minimal" amount of planning is necessary. That’s
exactly what happened here.)
- don't just jump into the code
- OR stop and refactor when it starts getting complex
4) Don't demo an unstable version: (In their enthusiasm for
pleasing the customer, the team would occasionally add features at
the last minute. These features would have been developed in a hurry
without test-first development, so there would have been no unit
testing and little integration testing or application testing. As a
result, demos often failed to perform as expected. This was
embarrassing for the team.)
- unit test for each class
- application test for bunch of classes
- earlier stable version
- thin GUI
It’s easy to see from these two project retrospectives, that what
one team learns from a development experience often has applicability
to other teams. Perhaps you’ve had the chance to observe many of
these "lessons learned" yourself. I hope you’ve enjoyed
learning a little more about two valuable development practices:
pairing and retrospectives. You can read more about them in my
previous articles and if you have questions, please feel free to
contact me.
References
[Kerth01] Project Retrospectives: A Handbook for Team Reviews,
Norman L. Kerth, Dorset House Publishing, 2001.
 |
About the Author
http://www.lindarising.org
risingl@acm.org
Linda Rising has a Ph.D. from Arizona
State University in the area of object-based design metrics.
Her background includes university teaching as well as work
in industry in telecommunications, avionics, and strategic
weapons systems. She is the author of numerous articles and
has published three books: Design Patterns in
Communications, The Pattern Almanac 2000, and A Patterns
Handbook. She is currently writing a book with Mary Lynn
Manns: Introducing Patterns (or any Innovation) into
Organizations, to appear in 2004. |
[
Back to Top ]
|