Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Bailey O.H.Embedded systems.Desktop integration.2005

.pdf
Скачиваний:
73
Добавлен:
23.08.2013
Размер:
9.53 Mб
Скачать

380

Chapter 9 / The PIC Prototype

 

 

Defining a USB Device to the Host System

Developing a good working USB device can be tricky. Consider the fact that if the USB descriptors are wrong your device will simply be ignored by the host system. Even worse, you may need to purchase a USB analyzer, which will cost upward of $1,000. There are software tools available to make things easier. The PICDEM USB kit includes software to help get the USB descriptors correct. There is also a tool that will walk you through the process of developing an HID-based USB device and even generate the code for the PIC and Windows application.

While it’s true we are developing for cross-platform use, using this tool leaves us with only the need to develop the Linux/UNIX USB application interface. Of more importance is the fact that this tool builds both ends of the USB code, which may seem to be a minor point but is a very important development fact. The tool I’m describing is HIDmaker from Trace Systems. Before we walk through a sample USB device definition, please review how the USB interface works. Having said

Figure 9-12

Chapter 9 / The PIC Prototype

381

 

 

that, let’s build a simple USB device with HIDmaker. After installation HIDmaker will reside in a program group under Trace. To start HIDmaker, select Start | Programs | Trace | HIDmaker.

1.Since this is our first USB device, choose NORMAL Device and press Next. A project info screen will appear.

Chapter 9

Figure 9-13

2.In this window we enter a path to our project and a project name. This is followed by a description string and manufacturer string. The check boxes at the far right indicate these will be in the PIC firmware. The next two fields are vendor and product IDs. For development and test purposes you can use the default contents, but you must get your own IDs from usb.org before going to market. The next fields are the release number, which can also be inserted into the firmware, a device serial number, and a USB class name. Input your information into these fields and press the Next button.

3.The next window is where a lot of the work that HIDmaker performs is done. This is a very important window because it defines our descriptors and variables. For our example we

382

Chapter 9 / The PIC Prototype

 

 

will use the default values for the Configuration and Interface descriptions. Our device has its own power supply so check the Device has its own power supply radio button.

4.We will not be using remote wakeup in our prototype so check Not Used by Device. Next, we will select EP1 In: Interrupt with a value of 250 ms, and EP1 Out: Interrupt with a value of 250 ms. It’s important to remember that all communications are initiated by the host system, so these interrupt interval setting will be triggered by the host, not the slave (embedded system). Your screen should look similar to the following:

Figure 9-14

5.Now it’s time to define our data, so press the Define Data button. Before we continue it’s important to note that all data views are from the host. So input would be input to the host and output would be output from the host. With that in mind, let’s define our data variables. When you press the Define Data button, you will be presented with a screen similar to the following:

Chapter 9 / The PIC Prototype

383

 

 

Figure 9-15

actually get much more complicated, but let’s walk before we

9

Chapter

6. For our first sample we will define two data items. We can

 

run. Click the Data Item button, then click inside the

 

recessed open area. You should see a button appear. Repeat

 

this process once more for our second data item; your screen

 

should look like Figure 9-15. To set the parameters for each

 

item, double-click on that item and a Data Item Properties

 

dialog will appear.

 

7. Select Input from the Data Type drop-down dialog box and

 

Usage ID 1 from the Usage Info box. Check the Data radio

 

button since this is not a constant and the Variable radio but-

 

ton since this is not a keyboard array of characters. Select

 

the Absolute, No Wrap, Linear, No Preferred State, No

 

Null State, and Bit Field radio buttons. The Report Size in

 

bits should be 8, or the size of a byte. The Report Count will

 

be 12 and will contain the string “Hello World” and a null

 

terminator. Go to the Name field and name this HelloData.

 

When the host initiates an input interrupt to the PIC, the

 

message sent will be “Hello World.” Your screen should look

 

similar to the following:

 

384

Chapter 9 / The PIC Prototype

 

 

Figure 9-16

8.Click the OK button to return to the Visual Data Designer. Next, click the second data item and define it as Output with a Usage ID of 2, and a Report Count of 14. This will send a string “Goodbye World” and a terminating null character. Name this GoodbyeData and press OK. Upon returning to the Visual Data Designer this time, select File | Save As to save our data definitions. After the data definitions have been saved, close the Visual Data Designer and press the Next button.

9.Now we are ready to generate code for both the USB device and the Windows host. We have a nice selection of languages for the PIC. HIDmaker supports Assembler, PicBasic Pro from microEngineering Labs, HI-TECH C (which is also ANSI C), and CCS C. You can choose more than one; as you can see I’ve chosen all but Assembler. On the host side we have Visual Basic 6, Delphi, and C++ Builder for our choices. I’ve chosen C++ Builder and Delphi. Press the Next button to generate your code; a summary will be displayed along with the contents of each generated file. At this point you can press the Finish button to leave HIDmaker.

Chapter 9 / The PIC Prototype

385

 

 

Figure 9-17

Finishing the Communications Tasks

With our USB communications handler finished, we need to move on to adding TTL serial I/O support for the remaining communications methods. Before we do that, however, I would suggest that you compile and test both the PIC and Windows projects to check for compiler errors.

Chapter 9

386

Chapter 9 / The PIC Prototype

 

 

The NetBurner SB72 Board

We covered the NetBurner TCP/IP interface in Chapter 8. In this chapter we will use the same hardware but use the UDP protocol instead. UDP stands for User Datagram Protocol. It differs from TCP/IP in that a session is connectionless. Instead of having a dedicated connection like TCP, UDP allows packets to be sent and received from multiple IP addresses without a dedicated session with any one address.

UDP does not promise that the data sent will ever be received. Since our implementation is on a LAN and is not currently required to be Internet accessible, UDP should provide a high degree of reliability. If we were using this across the Internet we probably would not select UDP, but this protocol has some advantages for working in a LAN environment. One example of this benefit is the ability to have temperature updates broadcast across the network to multiple workstations. If our thermostat were in use in a cold storage warehouse, this would allow anyone to “dial-in” to the thermostat and get real-time temperature and alarm data. Controlling the thermostat could become a nightmare unless we filter who or which terminals can access the control functions. This could be as simple as checking the origination IP address to see if it is an authorized control station. We could also add a password so that the user could be authenticated and allow access by only certain individuals from specific workstations. In short, there are several ways to provide controls prohibiting unauthorized use.

We could use the TCP/IP methods from Chapter 8 and they would work just fine. The TTL serial interface is identical in both situations. The following listing illustates one way of implementing UDP.

Chapter 9 / The PIC Prototype

387

 

 

Listing 9-7

/****************************************************************************** UDP Test Program — Copyright 2004, Oliver H. Bailey

This program is for Embedded Systems, Desktop Integration Book

*****************************************************************************/

#include "predef.h" #include <stdio.h> #include <ctype.h> #include <startnet.h> #include <ucos.h> #include <udp.h> #include <autoupdate.h> #include <string.h> #include <taskmon.h>

extern "C"

{

void UserMain(void *pd);

}

// We have to use 4-byte alignment for the NetBurner

DWORD UdpTestStk[USER_TASK_STK_SIZE] attribute_((aligned(4)));

/******************************************************************************* The UDP Read Packet Function. - Waits for 100 clock ticks and then returns if no data arrived.

*******************************************************************************/

void UDPRead(void *pd)

{

int UDP_port = (int) pd;

// UDP Port Number assignment

printf("Using port #%d\n", UDP_port);

// Print Port Number

OS_FIFO Read_fifo;

// Create Read fifo

OSFifoInit(&Read_fifo);

// and Initialize the fifo

RegisterUDPFifo(UDP_port, &Read_fifo);

// Register the port number and buffer

while (1)

// Do Forever

{

 

UDPPacket upkt(&Read_fifo, 100);

// Return on data or timeout

Chapter 9

388

 

Chapter 9 / The PIC Prototype

 

 

 

 

 

 

if (upkt.Validate())

// If we receive valid data, process

 

{

 

 

 

WORD Data_len = upkt.GetDataSize();

// Data length

 

printf("Got %d UDP Bytes From :", (int) Data_len);

 

ShowIP(upkt.GetSourceAddress());

// Data Source IP Address

 

printf("\n");

 

 

ShowData(upkt.GetDataBuffer(), Data_len);

// Display actual data

 

printf("\n");

 

 

}

 

// End of Valid Packet Data Handler

}

 

 

// End of do forever loop

}

 

 

// End of UDPRead

const char *AppName = "UDP Example";

 

void UserMain(void *pd)

 

{

 

int UDP_portnum;

// PortNumber Variable

IPADDR UDP_addr;

// UDP Address Variable

char buffer[80];

// Buffer

InitializeStack();

// Initialize the Program Stack

EnableAutoUpdate();

// Enable Auto Update feature

EnableTaskMonitor();

// Enable Task Monitor

printf("UDP Test \n");

// Program Purpose

printf("Input the port number?\n");

// Get Port Number from User

scanf("%d", &UDP_portnum);

// Scan and Store

printf("\nEnter the IP Address to send to?");

// Get Target IP address

buffer[0] = 0;

// Buffer element = 0

while (buffer[0] == 0)

// No keyboard data, wait

{

 

gets(buffer);

// else, get Keyboard data

}

 

UDP_addr = AsciiToIp(buffer);

// Convert to dot notation

// Print Port Chosen

 

printf("%d UDP Port in use ", UDP_portnum);

 

ShowIP(UDP_addr);

// Print IP Address

printf("\n");

 

 

Chapter 9 / The PIC Prototype

389

 

 

 

 

OSChangePrio(MAIN_PRIO);

// Bump up task priority

 

OSTaskCreate(UDPRead,

// Let’s create a blocking read task

 

(void *) UDP_portnum,

 

 

 

&UdpTestStk[USER_TASK_STK_SIZE],

 

 

 

UdpTestStk,

 

 

 

MAIN_PRIO - 1);

// Make it lower priority

 

while (1)

// Another Endless Loop

 

{

 

 

 

buffer = "Hello World\n";

// The infamous Hello World

 

printf("Sending %s on UDP port %d to IP Address ", buffer, UDP_portnum);

 

ShowIP(UDP_addr);

// Display Target IP Address

 

UDPPacket pkt;

// Create a UDPPacket instance

 

pkt.SetSourcePort(UDP_portnum);

// Select Source Port Number

 

pkt.SetDestinationPort(UDP_portnum);

// Set Destination Port Number

 

pkt.AddData(buffer);

// Put buffer data in transfer buffer

 

pkt.AddDataByte(0);

// Add terminating NULL

 

pkt.Send(UDP_addr);

// Send it to the destination address

 

printf("\n");

};

}

This program is made up of two main tasks, each contained in its own do…forever loop. The first task checks for valid incoming UDP data. If no data is received in 100 clock ticks, then it starts the wait cycle over again. The second task sends UDP data repeatedly.

This is a very simple demo for the NetBurner device. We could add multicasting, which allows support for broadcasting temperature data to multiple receivers. The purpose of this program is to get you familiar with the differences between TCP/IP and UDP. It also serves as a simple program that illustrates the process of setting up UDP data handlers in the NetBurner environment.

Chapter 9

Соседние файлы в предмете Электротехника