Файл: Embedded Systems Design - An Introduction to Processes Tools and Techniques (A. Berger, 2002).pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 13.06.2025

Просмотров: 2104

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

learned that the customer wants everything yesterday and is unwilling to pay for any of it. If you ask a customer whether he wants a feature, he’ll say yes every time. So, how do you avoid building an aircraft carrier when the customer really needs a fishing boat? First of all, don’t ask the customer whether the product should have a flight deck. Focus your efforts on understanding what the customer wants to accomplish and then extend his requirements to your product. As a result, the product and features you define are an abstraction and a distillation of the needs of your customer.

A common factor for the successful products was that the design team shared a common vision of the product they were designing. When asked about the product, everyone involved — senior management, marketing, sales, quality assurance, and engineering — would provide the same general description. In contrast, many failed products did not produce a consistent articulation of the project goals. One engineer thought it was supposed to be a low-cost product with medium performance. Another thought it was to be a high-performance, medium-cost product, with the objective to maximize the performance-to-cost ratio. A third felt the goal was to get something together in a hurry and put it into the market as soon as possible.

Another often-overlooked part of the product-specification phase is the

development tools required to design the product. igure 1.2 shows the embedded

Y

life cycle from a different perspective. This “design tools view” of the development

cycle highlights the variety of tools needed byLembedded developers.

F

When I designed in-circuit emulators, I saw products that were late to market

because the engineers did not have access to the best tools for the job. For

M

example, only a third of the hard-core embedded developers ever used in-circuit

emulators, even though they were the tools of choice for difficult debugging

problems.

A

E

T

The development tools requirements should be part of the product specification to ensure that unreal expectations aren’t being set for the product development cycle and to minimize the risk that the design team won’t meet its goals.

Tip

One of the smartest project development methods of which I’m

aware is to begin each team meeting or project review meeting by

showing a list of the project musts and wants. Every project

stakeholder must agree that the list is still valid. If things have

changed, then the project manager declares the project on hold until

the differences are resolved. In most cases, this means that the

project schedule and deliverables are no longer valid. When this

happens, it’s a big deal—comparable to an assembly line worker in

an auto plant stopping the line because something is not right with

the manufacturing process of the car.

In most cases, the differences are easily resolved and work continues, but not always. Sometimes a competitor may force a re-evaluation of the product features. Sometimes, technologies don’t pan out, and an alternative approach must be found. Since the alternative approach is generally not as good as the primary approach, design compromises must be factored in.

Team-Fly®


Hardware/Software Partitioning

Since an embedded design will involve both hardware and software components, someone must decide which portion of the problem will be solved in hardware and which in software. This choice is called the "partitioning decision."

Application developers, who normally work with pre-defined hardware resources, may have difficulty adjusting to the notion that the hardware can be enhanced to address any arbitrary portion of the problem. However, they've probably already encountered examples of such a hardware/software tradeoff. For example, in the early days of the PC (i.e., before the introduction of the 80486 processor), the 8086, 80286, and 80386 CPUs didn’t have an on-chip floating-point processing unit. These processors required companion devices, the 8087, 80287, and 80387 floating-point units (FPUs), to directly execute the floating-point instructions in the application code.

If the PC did not have an FPU, the application code had to trap the floating-point instructions and execute an exception or trap routine to emulate the behavior of the hardware FPU in software. Of course, this was much slower than having the FPU on your motherboard, but at least the code ran.

As another example of hardware/software partitioning, you can purchase a modem card for your PC that plugs into an ISA slot and contains the modulation/demodulation circuitry on the board. For less money, however, you can purchase a Winmodem that plugs into a PCI slot and uses your PC’s CPU to directly handle the modem functions. Finally, if you are a dedicated PC gamer, you know how important a high-performance video card is to game speed.

If you generalize the concept of the algorithm to the steps required to implement a design, you can think of the algorithm as a combination of hardware components and software components. Each of these hardware/software partitioning examples implements an algorithm. You can implement that algorithm purely in software (the CPU without the FPU example), purely in hardware (the dedicated modem chip example), or in some combination of the two (the video card example).

Laser Printer Design Algorithm

Suppose your embedded system design task is to develop a laser printer. Figure 1.3 shows the algorithm for this project. With help from laser printer designers, you can imagine how this task might be accomplished in software. The processor places the incoming data stream — via the parallel port, RS-232C serial port, USB port, or Ethernet port — into a memory buffer.

Figure 1.3: The laser printer design.

A laser printer design as an algorithm. Data enters the printer and must be transformed into a legible ensemble of carbon dots fused to a piece of paper.

Concurrently, the processor services the data port and converts the incoming data stream into a stream of modulation and control signals to a laser tube, rotating mirror, rotating drum, and assorted paper-management “stuff.” You can see how this would bog down most modern microprocessors and limit the performance of the system.

You could try to improve performance by adding more processors, thus dividing the concurrent tasks among them. This would speed things up, but without more information, it’s hard to determine whether that would be an optimal solution for the algorithm.

When you analyze the algorithm, however, you see that certain tasks critical to the performance of the system are also bounded and well-defined. These tasks can be easily represented by design methods that can be translated to a hardware-based solution. For this laser printer design, you could dedicate a hardware block to the process of writing the laser dots onto the photosensitive surface of the printer drum. This frees the processor to do other tasks and only requires it to initialize and service the hardware if an error is detected.

This seems like a fruitful approach until you dig a bit deeper. The requirements for hardware are more stringent than for software because it’s more complicated and costly to fix a hardware defect then to fix a software bug. If the hardware is a custom application-specificc IC (ASIC), this is an even greater consideration because of the overall complexity of designing a custom integrated circuit. If this approach is deemed too risky for this project, the design team must fine-tune the software so that the hardware-assisted circuit devices are not necessary. The riskmanagement trade-off now becomes the time required to analyze the code and decide whether a software-only solution is possible.

The design team probably will conclude that the required acceleration is not possible unless a newer, more powerful microprocessor is used. This involves costs as well: new tools, new board layouts, wider data paths, and greater complexity. Performance improvements of several orders of magnitude are common when


specialized hardware replaces software-only designs; it’s hard to realize 100X or 1000X performance improvements by fine-tuning software.

These two very different design philosophies are successfully applied to the design of laser printers in two real-world companies today. One company has highly developed its ability to fine-tune the processor performance to minimize the need for specialized hardware. Conversely, the other company thinks nothing of throwing a team of ASIC designers at the problem. Both companies have competitive products but implement a different design strategy for partitioning the design into hardware and software components.

The partitioning decision is a complex optimization problem. Many embedded system designs are required to be

Price sensitive

Leading-edge performers

Non-standard

Market competitive

Proprietary

These conflicting requirements make it difficult to create an optimal design for the embedded product. The algorithm partitioning certainly depends on which processor you use in the design and how you implement the overall design in the hardware. You can choose from several hundred microprocessors, microcontrollers, and custom ASIC cores. The choice of the CPU impacts the partitioning decision, which impacts the tools decisions, and so on.

Given this n-space of possible choices, the designer or design team must rely on experience to arrive at an optimal design. Also, the solution surface is generally smooth, which means an adequate solution (possibly driven by an entirely different constraint) is often not far off the best solution. Constraints usually dictate the decision path for the designers, anyway. However, when the design exercise isn’t well understood, the decision process becomes much more interesting. You’ll read more concerning the hardware/software partitioning problem in Chapter 3.

Iteration and Implementation

(Before Hardware and Software Teams Stop Communicating)

The iteration and implementation part of the process represents a somewhat blurred area between implementation and hardware/software partitioning (refer to Figure 1.1 on page 2) in which the hardware and software paths diverge. This phase represents the early design work before the hardware and software teams build “the wall” between them.

The design is still very fluid in this phase. Even though major blocks might be partitioned between the hardware components and the software components, plenty of leeway remains to move these boundaries as more of the design constraints are understood and modeled. In Figure 1.2 earlier in this chapter, Mann represents the iteration phase as part of the selection process. The hardware designers might be using simulation tools, such as architectural simulators, to model the performance of the processor and memory systems. The software designers are probably running code benchmarks on self-contained, single-board

computers that use the target micro processor. These single-board computers are often referred to as evaluation boards because they evaluate the performance of the microprocessor by running test code on it. The evaluation board also provides a convenient software design and debug environment until the real system hardware becomes available.

You’ll learn more about this stage in later chapters. Just to whet your appetite, however, consider this: The technology exists today to enable the hardware and software teams to work closely together and keep the partitioning process actively engaged longer and longer into the implementation phase. The teams have a greater opportunity to get it right the first time, minimizing the risk that something might crop up late in the design phase and cause a major schedule delay as the teams scramble to fix it.

Detailed Hardware and Software Design

This book isn’t intended to teach you how to write software or design hardware. However, some aspects of embedded software and hardware design are unique to the discipline and should be discussed in detail. For example, after one of my lectures, a student asked, “Yes, but how does the code actually get into the microprocessor?” Although well-versed in C, C++, and Java, he had never faced having to initialize an environment so that the C code could run in the first place. Therefore, I have devoted separate chapters to the development environment and special software techniques.

I’ve given considerable thought how deeply I should describe some of the hardware design issues. This is a difficult decision to make because there is so much material that could be covered. Also, most electrical engineering students have taken courses in digital design and microprocessors, so they’ve had ample opportunity to be exposed to the actual hardware issues of embedded systems design. Some issues are worth mentioning, and I’ll cover these as necessary.

Hardware/Software Integration

The hardware/software integration phase of the development cycle must have special tools and methods to manage the complexity. The process of integrating embedded software and hardware is an exercise in debugging and discovery. Discovery is an especially apt term because the software team now finds out whether it really understood the hardware specification document provided by the hardware team.

Big Endian/Little Endian Problem

One of my favorite integration discoveries is the “little endian/big endian” syndrome. The hardware designer assumes big endian organization, and the software designer assumes little endian byte order. What makes this a classic example of an interface and integration error is that both the software and hardware could be correct in isolation but fail when integrated because the “endianness” of the interface is misunderstood.

Suppose, for example that a serial port is designed for an ASIC with a 16-bit I/O bus. The port is memory mapped at address 0x400000. Eight bits of the word are the data portion of the port, and the other eight bits are the status portion of the port. Even though the hardware designer might specify what bits are status and


what bits are data, the software designer could easily assign the wrong port address if writes to the port are done as byte accesses (Figure 1.5).

Figure 1.5: An example of the endianness problem in I/O addressing.

If byte addressing is used and the big endian model is assumed, then the algorithm should check the status at address 0x400001. Data should be read from and written to address 0x400000. If the little endian memory model is assumed, then the reverse is true. If 16-bit addressing is used, i.e., the port is declared as

unsigned short int * io_port ;

then the endianness ambiguity problem goes away. This means that the software might become more complex because the developer will need to do bit manipulation in order to read and write data, thus making the algorithm more complex.

The Holy Grail of embedded system design is to combine the first hardware prototype, the application software, the driver code, and the operating system software together with a pinch of optimism and to have the design work perfectly out of the chute. No green wires on the PC board, no “dead bugs,” no redesigning the ASICs or Field Programmable Gate Arrays (FPGA), and no rewriting the software. Not likely, but I did say it was the Holy Grail.

Note Here “dead bugs” are extra ICs glued to the board with their I/O pins facing up. Green wires are then soldered to their “legs” to patch them into the rest of the circuitry.

You might wonder why this scenario is so unlikely. For one thing, the real-time nature of embedded systems leads to highly complex, nondeterministic behavior that can only be analyzed as it occurs. Attempting to accurately model or simulate the behavior can take much longer than the usable lifetime of the product being developed. This doesn’t necessarily negate what I said in the previous section; in fact, it is shades of gray. As the modeling tools improve, so will the designer’s ability to find bugs sooner in the process. Hopefully, the severity of the bugs that remain in the system can be easily corrected after they are uncovered. In

Embedded Systems Programming[1], Michael Barr discusses a software architecture that anticipates the need for code patches and makes it easy to insert them without major restructuring of the entire code image. I devote Chapters 6, , and to debugging tools and techniques.

Debugging an Embedded System

In most ways, debugging an embedded system is similar to debugging a hostbased application. If the target system contains an available communications channel to the host computer, the debugger can exist as two pieces: a debug kernel in the target system and a host application that communicates with it and manages the source database and symbol tables. (You’ll learn more about this later on as well.) Remember, you can’t always debug embedded systems using only the methods of the host computer, namely a good debugger and printf() statements.

Many embedded systems are impossible to debug unless they are operating at full speed. Running an embedded program under a debugger can slow the program down by one or more orders of magnitude. In most cases, scaling all the real-time dependencies back so that the debugger becomes effective is much more work than just using the correct tools to debug at full speed.

Manufacturers of embedded microprocessors also realize the difficulty of controlling these variables, so they’ve provided on-chip hooks to assist in the debugging of embedded systems containing their processors. Most designers won’t even consider using a microprocessor in an embedded application unless the silicon manufacturer can demonstrate a complete tool chain for designing and debugging its silicon.

In general, there are three requirements for debugging an embedded or real-time system:

Run control — The ability to start, stop, peak, and poke the processor and memory.

Memory substitution — Replacing ROM-based memory with RAM for rapid and easy code download, debug, and repair cycles.

Real-time analysis — Following code flow in real time with real-time trace analysis.

For many embedded systems, it is necessary also to integrate a commercial or inhouse real-time operating system (RTOS) into the hardware and application software. This integration presents its own set of problems (more variables); the underlying behavior of the operating system is often hidden from the designers because it is obtained as object code from the vendor, which means these bugs are now masked by the RTOS and that another special tool must be used.

This tool is usually available from the RTOS vendor (for a price) and is indispensable for debugging the system with the RTOS present. The added complexity doesn’t change the three requirements previously listed; it just makes them more complex. Add the phrase “and be RTOS aware” to each of the three listed requirements, and they would be equally valid for a system containing a RTOS.