User Tools

Site Tools


lab_10

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

lab_10 [2019/04/08 20:11] (current)
Line 1: Line 1:
 +====== Lab 10: Using Queues to Communicate with Peripherals ======
 +===== Overview =====
  
 +In this lab you shall use the principles taught in section 5.7 of the book. You shall modify code from a previous lab to use a queue for communicating button presses on the keypad.
 +
 +===== Specifications =====
 +
 +You must use a queue to pass a message when buttons are pressed on the keypad (e.g. button 5 was pressed). You will do this by modifying the code from Lab 8. Create a new project and copy and paste the code from Lab 8 into the new project. This ensures you still have the original code for reference.
 +
 +Remove the tasks for the ADC, DAC, and PWM that were included in Lab 8. They are not needed for this lab. You can also remove any functions that are unnecessary after these tasks have been removed.
 +
 +One of the purposes of this lab is to ensure that you have learned how to break your code into separate .c and .h files. You must write/​develop your own queue code that does not recopy data as shown in the book. You must 
 +move pointers to the top and bottom of the queue instead of always recopying data (the book code examples, unfortunately,​ implement a recopying method). Nobody does this.
 +
 +You must place these functions in a separate .c file from the one that contains your main() function. Place any declarations of data types or structs into a separate .h header file. For example, you might place the queue functions in queue.c and create a queue.h header file.
 +
 +Remove all shared variables you used for communication between the keypad SM and clock SM. A single queue should be sufficient for communication between these state machines. The keypad SM shall push messages into the queue and the clock SM shall pop messages out. The messages will tell what keys have been pressed on the keypad. Only send one message for each button press. In other words, if a button is held down do not send multiple messages.
 +
 +When complete the behavior of the clock system should still be the same as after Lab 6 or Lab 8.
 +
 +===== Hints =====
 +
 +Here are some suggestions for the queue implementation.
 +  - Don't use the copying approach shown in the book (this is a requirement,​ actually).
 +  - You can use the .h and .c templates that I provide below.
 +  - queuetest.c shows how to use the queue code.
 +  - The advantage of the code below is that it allows you to have as many different queues as you might like. This code allows this because you pass the queue struct into all queuePop() and queuePush() functions. ​
 +  - Remember that malloc() allocates a chunk of memory for your program. The size of the chunk is the number of bytes that you ask for.
 +  - You don't have to use a long data type - just be consistent in both the queue_t struct and the call to malloc() so that you get the right amount of memory. In the example code below, I used type ''​int''​.
 +  - Reference the malloc'​d memory as a simple array. C makes this easy. In the code below you can access the data variable in the ''​queue_t struct''​ as ''​data[in_index]'',​ etc. There is no good reason to use pointers here (that I can see). Study the printQueue() function contained in the queue.c code to understand this syntax better.
 +
 +**queue.h:​**
 +<​code>​
 +#ifndef QUEUE_H
 +#define QUEUE_H
 +
 +typedef struct {
 +  unsigned short indexIn;
 +  unsigned short indexOut;
 +  unsigned short size;
 +  int* data;
 +} queue_t;
 +
 +void queueInit(queue_t* q, unsigned short size);
 +unsigned char queueFull(queue_t* q);
 +unsigned char queueEmpty(queue_t* q);
 +void queuePush(queue_t* q, unsigned int value);
 +int queuePop(queue_t* q);
 +void printQueue(queue_t* q);
 +#endif
 +</​code>​
 +
 +**queue.c:​**
 +
 +<​code>​
 +#include <​stdio.h>​
 +#include <​stdlib.h>​
 +#include "​queue.h"​
 +
 +// Standard queue implementation that leaves one spot empty so easier to check for full/empty.
 +void queueInit(queue_t* q, unsigned short size) {
 +  q->​indexIn = 0;
 +  q->​indexOut = 0;
 +  q->size = size;
 +  q->data = malloc(size * sizeof(int));​
 +}
 +
 +// Helper function. Not visible to user.
 +unsigned int incrementIndex(unsigned int index, unsigned short size) {
 +}
 +
 +unsigned char queueFull(queue_t* q) {
 +}
 +
 +unsigned char queueEmpty(queue_t* q) {
 +}
 +
 +// Does nothing if the queue is full.
 +void queuePush(queue_t* q, unsigned int value) {
 +}
 +
 +// Does nothing if the queue is empty.
 +int queuePop(queue_t* q) {
 +}
 +
 +void printQueue(queue_t* q) {
 +  int indexOutTmp;​
 +  if (queueEmpty(q)) {
 +    printf("​Queue is empty.\n"​);​
 +    return;
 +  }
 +  // Queue is not empty, print out its contents but don't disturb its state. Use a temp out index.
 +  // This for-loop looks a little complicated. Just study it carefully and you will see what it does.
 +  // You should be able to study this syntax to see how to access the data slot in the functions
 +  // that you need to write.
 +  for (indexOutTmp = q->​indexOut;​ indexOutTmp != q->​indexIn;​ indexOutTmp = incrementIndex(indexOutTmp,​ q->​size)) {
 +    printf("​%d\n",​ q->​data[indexOutTmp]);​
 +  }
 +}
 +
 +</​code>​
 +
 +**queuetest.c:​**
 +<​code>​
 +#include <​stdio.h>​
 +#include "​queue.h"​
 +
 +#define QUEUE_SIZE 4
 +
 +int main() {
 +  queue_t q;
 +  queueInit(&​q,​ QUEUE_SIZE);​
 +  queuePush(&​q,​ 1);
 +  queuePush(&​q,​ 2);
 +  queuePush(&​q,​ 3);
 +
 +  printf("​printing contents of queue.\n"​);​
 +  printQueue(&​q);​
 +  printf("​done printing contents of queue.\n"​);​
 +
 +  printf("​%d\n",​ queuePop(&​q));​
 +  queuePush(&​q,​ 4);
 +  printf("​%d\n",​ queuePop(&​q));​
 +  queuePush(&​q,​ 5);
 +  printf("​%d\n",​ queuePop(&​q));​
 +  ​
 +  printf("​printing contents of queue.\n"​);​
 +  printQueue(&​q);​
 +  printf("​done printing contents of queue.\n"​);​
 +
 +  printf("​%d\n",​ queuePop(&​q));​
 +  printf("​%d\n",​ queuePop(&​q));​
 +  printf("​%d\n",​ queuePop(&​q));​
 +}
 +</​code>​
 +
 +===== Grading =====
 +
 +Demonstrate your working clock to the TA. Turn in the portions of your code that are relative to your queue, which should include queue.c(and queue.h, if altered), and the portions of your original code(which includes main()) that display proper use of your queue. Many of the requirements in this lab are not readily apparent during pass-off, so make sure the code you hand in shows that you've met them all(good comments are helpful in seeing/​grading this!).
 +
 +Also report how long the lab took you, major bugs/​difficulties you encountered,​ and parts of the lab specs you felt were ambiguous.
lab_10.txt ยท Last modified: 2019/04/08 20:11 (external edit)