My Solution:

Assume that all undeclared variables are 8 bit integers

Assume at most 1 tempo change command in between each music event command

Assume that TNE ¹ 0 for all music commands

Assume that Temp ¹ 0 for all tempo commands

 

void tone_gen() interrupt T2 {

20    // play current event

2     *adc = (sin[t1]+sin[t2]+sin[t3])/3; 

2     t1 += stride1;

2     t2 += stride2;

2     t3 += stride3;

// check to see if current event is now previous event

2     if (!--sampleCount) { // sampleCount = samples remaining in current event    

            //done w/ previous event, get parameters for new current event

2           stride1 = newStride1;

2           stride2 = newStride2;

2           stride3 = newStride3;

8           sampleCount = newSampleCount;

2           if (!stride1) t1 = 0;         // clear t1 if stride1 = 0;

2           if (!stride2) t2 = 0;         // likewise for t2

2           if (!stride3) t3 = 0;         // likewise for t3

47          isr_send_signal(EVENT);       // Signal event task

      }    

}

 

void event() _task_ EVENT {

      setUpT2 for 10KHz timer interrupt;

      const X = ??; // see question 2

      initialize t1-3, stride1-3, newStride1-3 to zero;

      long sampleCount = newSampleCount = X;  // initialize sampleCount variables

      result = true;

      while (1) {

      //while current event plays

//compute parameters for next event by dequeueing and decodin g

1           while(result)

60                result = deQandDecode()) { // deQandDecode returns true if temp cmd

2                 newStride1 = lookupS[decode.f1]; // changes if command was an event

2                 newStride2 = lookupS[decode.f2]; // changes if command was an event
2                 newStride3 = lookupS[decode.f3]; // changes if command was an event

15                newSampleCount = decode.TNE * decode.tempo * X;

            }

      result = true;

      os_wait(K_SIG);

      }

 

}

Notes:

·         deQandDecode() pulls the appropriate number of bytes out of the queue and updates the global decode struct. Assume that this takes 60 cycles at most.

·         The serial code just runs the byte exchange protocol with the host, and it stuffs incoming bytes into the queue. Assume that Serial_Top requires 60 cycles at most, and that Serial_Bottom requires 20 cycles at most.

·         LookupS is a ROM table that converts the frequency (f1, f2, f3) to stride

 

 

Questions (50 points total)

1.      What is the maximum rate that the system can consume data in bytes/second (3pts)

 

Peak: 9600/8 is byte rate of serial port. Protocl requires two bytes so max rate is 1200/2 = 600.

Average: 4 bytes/Event * 16 Events/sec = 64 bytes/sec

 

 

 

2.      What is the right initial value of the constant X (4pts)

 

 

newSampleCount = decode.TNE * decode.tempo * X;

if TNE=tempo=1 then newSampleCount should be the number of samples in 1/16 of a sec.

10K/16 = 625

 

 

 

 

 

3.      In the left margin of the first page, write your estimate of the number of instruction cycles for each line of code in the ISR. What is the approximate worst-case average utilization for the tone_gen ISR (10pts)?

 

short path executes @ 10KHz

            Total instructions/sec = 10000*28 = 280Kcycles/sec

long path executes @16Hz in the worst case

            Total instructions/sec = 16*(71*2) = 2272 (negligible)

 

So, average worst case utilization = 280K/2.66M = 10.5%

 

 

 

 

 

Most people did not account for the two paths, which is way too conservative.


 

4.      Provide a numerical deadline constraint for the event task (this requires understanding my solution. Study the code and comments (10pts).

 

Event has a full beat to compute the next set of parameters for tone_gen in the worst case. So the deadline is 1/16 of a second from the end of an event. Expressed as a constraint

 

Let starting point of deadline be Tprev_end

Devent = min(Tnext_start)

but min(Tnext_start) >= Tprev_end+1/16sec so

Devent =  Tprev_end+1/16sec (in absolute time)

 

Don’t confuse Deadline w/ Minimum Deadline. Deadline is a requirement, Minimum deadline is a property of the implementation.

 

5.      Does EVENT always meet its deadline?  Draw a timing diagram to show your worst-case scenario, and explain your reasoning (10pts). In the diagram below, the space between the dotted lines represents 20 instruction cycles. Draw you timing diagram as accurately as you can to this scale.

 

 

 

 

 

Yes. According to the worst case, event does it job sometime between the first and second sample of the current event. If you said that the deadline was .1 then you should have answered NO to this.

 

 

 

 


 

 

 

         

 

 

 

 

 

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Therefore the entire bottom half can run

                       

 

                       

 

 

 

 

 

 

 

 

                       

6.      Provide a description for the functionality of write() for a Linux device driver that interacts with this system.  If your device driver requires an interrupt routine, describe its role and how it communicates with the write() function (7pts).

 

 

Write should put the music into a queue. The ISR runs the byte exchange protocol as long as there is data in the queue (write might have to get things started by sending a byte).

 

If the queue is full then write should either block or return an error.

 

User program should send in a large chunk of music then continue on with other processing. 10K bytes is good for 208 seconds of music!

 

 

 

 

Main problem: linux is not playing the music, just sending data!

 

 

 

 

 

 

 

 

 

 

 

7. What should deQandDecode() do if the queue is empty  (6pts)? Explain.

 

It could clear out the nextStrideX and tX values to make the music stop, then return either true or false. If true the busy wait will ensue, otherwise you won’t get a chance to start the music until the next 16th of a second. One option would be to change X to a small value and set TNE, Tempo to 1 so that you go to sleep, but not for a whole 1/16th