• No results found

How do we change Program 6.1 to run using Port A

In document Embedded Systems Shape the World (Page 87-94)

In Program 6.1 the assumption was the software module had access to all of Port F. In other words, this software owned all pins of Port F. In most cases, a software module needs access to only some of the port pins. If two or more software modules access the same port, a conflict will occur if one module changes modes or output values set by another module. It is good software design to write friendly software, which only affects the individual pins as needed. Friendly software does not change the other bits in a shared register. Conversely, unfriendly software modifies more bits of a register than it needs to. The difficulty of unfriendly code is each module will run properly when tested by itself, but weird bugs result when two or more modules are combined.

Consider the problem that a software module needs to output to just Port A bit 7. After enabling the clock for Port A, we use read-modify-write software to initialize just pin 7. The following initialization does not modify the configurations for the other 7 bits in Port A. Unlocking is not required for PA7 (just PD7 and PF0 require unlocking)

SYSCTL_RCGC2_R |= 0x00000001; // 1) activate clock for Port A delay = SYSCTL_RCGC2_R; // allow time for clock to start GPIO_PORTA_AMSEL_R &= ~0x80; // 3) disable analog on PA7 GPIO_PORTA_PCTL_R &= ~0xF0000000; // 4) PCTL GPIO on PA7 GPIO_PORTA_DIR_R |= 0x80; // 5) PA7 out

GPIO_PORTA_AFSEL_R &= ~0x80; // 6) disable alt funct on PA7 GPIO_PORTA_DEN_R |= 0x80; // 7) enable digital I/O on PA7

There is no conflict if two or more modules enable the clock for Port A. There are two ways on LM4F/TM4C microcontrollers to access individual port bits. The first method is to use read-modify-write software to change just one pin. A read-or-read-modify-write sequence can be used to set bits.

LDR R1, =GPIO_PORTA_DATA_R

A read-and-write sequence can be used to clear one or more bits.

LDR R1, =GPIO_PORTA_DATA_R

The second method uses the bit-specific addressing. The LM4F/TM4C family implements a flexible way to access port pins. This bit-specific addressing doesn’t work for all the I/O registers, just the parallel port data registers. The mechanism allows collective access to 1 to 8 bits in a data port. We define eight address offset constants in Table 6.3. Basically, if we are interested in bit b, the constant is 4*2b. There 256 possible bit combinations we might be interested in accessing, from all of them to none of them. Each possible bit combination has a separate address for accessing that combination. For each bit we are interested in, we add up the corresponding constants from Table 6.3 and then add that sum to the base address for the port. The base addresses for the data ports can be found Table 6.2. For example, assume we are interested in Port A bits 1, 2, and 3. The base address for Port A is 0x4000.4000, and the constants are 0x0008, 0x0010, and 0x0020. The sum of 0x4000.4000+0x0008+0x0010 +0x0020 is the address 0x4000.4038. If we read from 0x4000.4038 only bits 1, 2, and 3 will be returned. If we write to this address only bits 1, 2, and 3 will be modified.

If we wish to access bit Constant

7 0x0200

6 0x0100

5 0x0080

4 0x0040

3 0x0020

2 0x0010

1 0x0008

0 0x0004

Table 6.3. Address offsets used to specify individual data port bits.

The base address for Port A is 0x4000.4000. If we want to read and write all 8 bits of this port, the constants will add up to 0x03FC. Notice that the sum of the base address and the constants yields the 0x4000.43FC address used in Table 6.2 and Program 6.1. In other words, read and write operations to GPIO_PORTA_DATA_R will access all 8 bits of Port A. If we are interested in just bit 5 of Port A, we add 0x0080 to 0x4000.4000, and we can define this in C and in assembly as

#define PA5 (*((volatile unsigned long *)0x40004080)) PA5 EQU 0x40004080

Now, a simple write operation can be used to set PA5. The following code is friendly because it does not modify the other 7 bits of Port A.

PA5 = 0x20; // make PA5 high

A simple write sequence will clear PA5. The following code is also friendly.

PA5 = 0x00; // make PA5 low

A read from PA5 will return 0x20 or 0x00 depending on whether the pin is high or low, respectively. If PA5 is an output, the following code is also friendly.

PA5 = PA5^0x20; // toggle PA5

Note that the base address when computing the bit-specific address for PortA is 0x40004000, the following table lists the base addresses for the other ports.

Port Base address PortA 0x40004000 PortB 0x40005000 PortC 0x40006000 PortD 0x40007000 PortE 0x40024000 PortF 0x40025000

Table 6.4. Base Addresses for bit-specific addressing of ports A-F Checkpoint 6.5: What happens if we write to location 0x4000.4000?

Checkpoint 6.6: Specify a #define that allows us to access bits 7 and 1 of Port A. Use this #define to make both bits 7 and 1 of Port A high.

Checkpoint 6.7: Specify a #define that allows us to access bits 6, 1, 0 of Port B. Use this #define to make bits 6, 1 and 0 of Port B high.

To understand the port definitions in C, we remember #define is simply a copy paste. E.g., data = PA5;

becomes

data = (*((volatile unsigned long *)0x40004080));

To understand why we define ports this way, let’s break this port definition into pieces. First, 0x40004080 is the address of Port A bit 5. If we write just #define PA5 0x40004080 it will create data = 0x40004080;

which does not read the contents of PA5 as desired. This means we need to dereference the address. If we write #define PA5 (*0x40004080) it will create

data = (*0x40004080);

This will attempt to read the contents at 0x40004080, but doesn’t know whether to read 8 16 or 32 bits.

So the compiler gives a syntax error because the type of data does not match the type of (*0x40004080). To solve a type mismatch in C we typecast, placing a (new type) in front of the object we wish to convert. We wish force the type conversion to unsigned 32 bits, so we modify the definition to include the typecast,

#define PA5 (*((volatile unsigned long *)0x40004080))

The volatile is added because the value of a port can change beyond the direct action of the software. It forces the C compiler to read a new value each time through a loop and not rely on the previous value.

6.4. Debugging monitor using an LED

One of the important tasks in debugging a system is to observe when and where our software is executing. A debugging tool that works well for real-time systems is the monitor. In a real-time system, we need the execution time of the debugging tool to be small compared to the execution time of the program itself. Intrusiveness is defined as the degree to which the debugging code itself alters the performance of the system being tested. A monitor is an independent output process, somewhat similar to the print statement, but one that executes much faster and thus is much less intrusive. An LED attached to an output port of the microcontroller is an example of a BOOLEAN monitor. You can place LEDs on unused output pins. Software toggles these LEDs to let you know where and when your program is running. Assume an LED is attached to Port F bit 2. Program 6.2 will toggle the LED. We create a bit-specific address constant to access just PF2:

PF2 EQU 0x40025010 useful to see while the program is running. In particular, you add BL Toggle statements at strategic places within your system. It only takes 13 bus cycles to execute. Port G must be initialized so that bit 2 is an output before the debugging begins. You can either observe the LED directly or look at the LED control signals with a high-speed oscilloscope or logic analyzer. An LCD can be an effective monitor for small amounts of information. Inexpensive LCDs can display from 8 to 160 characters. Unfortunately, it takes about 50 µs to output each character, so the use of an LCD monitor might be intrusive. When using LED monitors it is better to modify just the one bit, leaving the other 7 as is. In this way, you can have additional LED monitors.

6.5. Hardware debugging tools

Microcomputer related problems often require the use of specialized equipment to debug the system hardware and software. Two very useful tools are the logic analyzer and the oscilloscope. A logic analyzer is essentially a multiple channel digital storage scope with many ways to trigger, see Figure 6.8. As a troubleshooting aid, it allows the experimenter to observe numerous digital signals at various points in time and thus make decisions based upon such observations. As with any debugging process, it is necessary to select which information to observe out of a vast set of possibilities. Any digital signal in the system can be connected to the logic analyzer. Figure 6.8 shows an 8-channel logic analyzer, but real devices can support 128 or more channels. One problem with logic analyzers is the massive amount of information that it generates. With logic analyzers (similar to other debugging techniques) we must strategically select which signals in the digital interfaces to observe and when to observe them. In particular, the triggering mechanism can be used to capture data at appropriate times eliminating the need to sift through volumes of output. Sometimes there are extra I/O pins on the microcontroller, not needed for the normal operation of the system (shown as the bottom two wires in Figure 6.8). In this case, we can connect the pins to a logic analyzer, and add software debugging instruments that set and clear these pins at strategic times within the software. In this way we can visualize the hardware/software timing.

Figure 6.8. A logic analyzer and example output.

An oscilloscope can be used to capture voltage versus time data. You can adjust the voltage range and time scale. The oscilloscope trigger is how and when the data will be capture. In normal mode, we measure patterns that repeat over and over, and we use the trigger (e.g., rising edge of channel 1) to freeze the image. In single shot mode, the display is initially blank, and once the trigger occurs, one trace is captured and display.

6.6. Chapter 6 Quiz

6.1 To make a pin a digital input, what value do you load into corresponding bits the following registers.

Assume it does not need an internal pullup

DIR

6.2 To make a pin a digital output, what value do you load into corresponding bits the following registers. Assume it does not need an internal pullup

DIR

6.5 Which debugging instrument can measure voltage versus time?

Heart Beat Oscilloscope Logic analyzer LED

6.6 Which debugging instrument can measure multiple digital signals versus time?

Heart beat Oscilloscope Logic analyzer LED

Chapter 7: Design and Development Embedded Systems - Shape the World Jonathan Valvano and Ramesh Yerraballi

In this chapter, we will begin by presenting a general approach to modular design. In specific, we will discuss how to organize software blocks in an effective manner. The ultimate success of an embedded system project depends both on its software and hardware. Computer scientists pride themselves in their ability to develop quality software. Similarly electrical engineers are well-trained in the processes to design both digital and analog electronics. Manufacturers, in an attempt to get designers to use their products, provide application notes for their hardware devices. The main objective of this class is to combine effective design processes together with practical software techniques in order to develop quality embedded systems. As the size and especially the complexity of the software increase, the software development changes from simple "coding" to "software engineering", and the required skills also vary along this spectrum. These software skills include modular design, layered architecture, abstraction, and verification. Real-time embedded systems are usually on the small end of the size scale, but never the less these systems can be quite complex. Therefore, both hardware and software skills are essential for developing embedded systems. Writing good software is an art that must be developed, and cannot be added on at the end of a project. Just like any other discipline (e.g., music, art, science, religion), expertise comes from a combination of study and practice. The watchful eye of a good mentor can be invaluable, so take the risk and show your software to others inviting praise and criticism. Good software combined with average hardware will always outperform average software on good hardware.

In this chapter we will introduce some techniques for developing quality software.

Learning Objectives:

Understand system development process as a life cycle

Take Requirements and formulate a problem statement.

Learn that an algorithm is a formal way to describe a solution

Define an algorithm with pseudo code or visually as a flowchart

Translate flowchart to code

Test in simulator (Test → Write code → Test → Write code … cycle)

Run on real board

7.1. Product Life Cycle

In this section, we will introduce the product development process in general. The basic approach is introduced here, and the details of these concepts will be presented throughout the remaining chapters of the book. As we learn software/hardware development tools and techniques, we can place them into the framework presented in this section. As illustrated in Figure 7.1, the development of a product follows an analysis-design-implementation-testing-deployment cycle. For complex systems with long life-spans, we transverse multiple times around the life cycle. For simple systems, a one-time pass may suffice.

Figure 2.3. Product life cycle.

During the analysis phase, we discover the requirements and constraints for our proposed system. We can hire consultants and interview potential customers in order to gather this critical information. A requirement is a specific parameter that the system must satisfy. We begin by rewriting the system requirements, which are usually written in general form, into a list of detailed specifications. In general, specifications are detailed parameters describing how the system should work. For example, a requirement may state that the system should fit into a pocket, whereas a specification would give the exact size and weight of the device. For example, suppose we wish to build a motor controller. During the analysis phase, we would determine obvious specifications such as range, stability, accuracy, and response time. There may be less obvious requirements to satisfy, such as weight, size, battery life, product life, ease of operation, display readability, and reliability. Often, improving the performance on one parameter can be achieved only by decreasing the performance of another. This art of compromise defines the tradeoffs an engineer must make when designing a product. A constraint is a limitation, within which the system must operate. The system may be constrained to such factors as cost, safety, compatibility with other products, use of specific electronic and mechanical parts as other devices, interfaces with other instruments and test equipment, and development schedule. The following measures are often considered during the analysis phase of a project:

Safety: The risk to humans or the environment

Accuracy: The difference between the expected truth and the actual parameter Precision: The number of distinguishable measurements

Resolution: The smallest change that can be reliably detected

Response time: The time between a triggering event and the resulting action Bandwidth: The amount of information processed per time

Maintainability: The flexibility with which the device can be modified

Testability: The ease with which proper operation of the device can be verified Compatibility: The conformance of the device to existing standards

Mean time between failure: The reliability of the device, the life of a product Size and weight: The physical space required by the system

Power: The amount of energy it takes to operate the system

Nonrecurring engineering cost (NRE cost): The one-time cost to design and test Unit cost: The cost required to manufacture one additional product

Time-to-prototype: The time required to design, build, and test an example system Time-to-market: The time required to deliver the product to the customer

Human factors: The degree to which our customers like/appreciate the product

In document Embedded Systems Shape the World (Page 87-94)