eecs 473 midterm exam
TRANSCRIPT
Page 1 of 12
EECS 473 Midterm Exam
Fall 2019 -- Answers
Name: ____________________________________ unique name: _____________
Sign the honor code:
I have neither given nor received aid on this exam nor observed anyone else doing so.
___________________________________
NOTES: 1. Closed book and Closed notes 2. There are 11 pages total for the exam as well as a handout which you will need for the last
question. 3. Calculators are allowed, but no PDAs, Portables, Cell phones, etc. Using a calculator to store
notes is not allowed nor is a calculator with any type of wireless capability. 4. You have about 120 minutes for the exam.
Be sure to show work and explain what you’ve done when asked to do so. That may be very
significant in the grading of this exam.
Page 2 of 12
1. Circle the letter in front of all the true statements. [6 points, -2 per wrong circle/lack of a
circle, minimum 0]
a) The command “mknod bob 2 4” creates a character device file named “bob” with a major
number of 2 and a minor number of 4.
b) Compared to a tantalum capacitor, the PCB power/ground plane has lower capacitance,
ESR, and ISL. – We took any answer here due to having “ISL” rather than “ESL”.
c) In a task with a “firm” deadline the results have no use after one the deadline has passed.
d) A “via” on a board is a connection between two traces on different board layers
e) Most PCB fab houses today require a clearance of at least 25 mills between traces.
f) A major disadvantage of alkaline batteries compared to lithium-polymer batteries is that
lithium-polymer batteries have a lower self-discharge rate.
g) Necking down a wire can be a useful way to shorten a wire, but if made too small for the
current going through the wire it could result in overheating or even melting.
2. Multiple choice—write letter in blank. [6 points, -2 per wrong/blank answer, minimum 0]
a) ____c_________ is to the Linux file model as writeMicroseconds is to the Arduino servo class.
a. Major number b. Minor number c. ioctl d. Busybox
b) _____a________ Rate monotonic scheduling doesn’t require which of the following:
a. dynamic priorities b. preemption c. knowledge of the period of the tasks
c) ____a_____ RMS scheduling can successful schedule – We took all answers here.
a. Any set of tasks whose total CPU utilization is less than 60%
b. Any tasks which FIFO could schedule
c. Any tasks which EDF could schedule
d. Any tasks which Round Robin could schedule
d) In one use case, Busybox uses _____b_________ to figure out what program is meant to be run.
a. The minor number b. argv[0] c. strcpy() d. a hard link
Page 3 of 12
3. Linux device drivers [8 points] Consider the following code found as the read function member of the file_operations struct for a Linux kernel module. It is associated with the device file "/dev/txx2" (so a read of the file /dev/txx2 will result in this function being called). Assume that everything is set up appropriately beforehand. Ignore the fact that copy_to_user’s return value is being ignored (it’s just a warning…).
const char s[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
ssize_t memory_read(struct file *filp, char *buf,
size_t count, loff_t *f_pos) {
printk("<1> fpos= %d\n",*f_pos);
/* Transferring data to user space */
copy_to_user (buf, s+*f_pos, 3);
/* Changing reading position as best suits */
if(*f_pos>=8)
return 0;
*f_pos+=4;
return 2;
}
Say that someone does a cat of /dev/txx2. a) What will appear in the log file? [3]
<1> fpos= 0 <1> fpos= 4 <1> fpos= 8
b) What will be printed by the cat command? [5] ABEF
Page 4 of 12
4. Decoupling capacitors [6 points]
The above graph shows the frequency vs. impedance for a given capacitor. Redraw the
graph showing the same information we instead put used 2 new capacitors (in parallel)
which each had the same ESR and capacitance but only 1/5th the ESL.
5. Linear regulators [6 points]
Say you have a linear regulator with an 6V input and a 3V output. If the load being driven by the
regulator is a constant 5 Ohms and the total power used by the system (regulator and load) is
4.0 Watts, how much is the quiescent current? Provide your answer in milliamps. Show your
work.
V=IR. P=IV
Load has V/R current, or 0.6A. So the regulator is supplying 0.6A. Total power for an ideal linear
regulator is then 6V*0.6A=3.6W. The rest of the power must be quiescent current. 0.4W/6V=66.7mA.
Page 5 of 12
6. Proving things in embedded systems [12 points, 4 each]
For each of these schemes show either that they can guarantee being able to schedule two tasks
with a total CPU utilization of 40% or provide a counterexample showing where they cannot. All
tasks must have an integer number of clock ticks for period and CPU utilization . Provide any
examples in terms of clock ticks.
Round Robin
Will always work.
If total CPU utilization is 40%, the CPU utilization of each task must be less than 40%.
Thus each task has a period that is at least twice as large as it’s CPU time. In round
robin with just 2 tasks the worst case is that a task runs every other tick. So a task that
has a worst-case CPU run time of N has more than 2N time to run and thus will always
meet its deadline.
FIFO
Won’t always work.
Task A CPU utilization 200, task period 1000.
Task B CPU utilization 2, task period 10.
Total CPU utilization is 40%.
At some point in Task A running, Task B will want to start running but task B will
continue running until completion so task B will not meet its deadline.
EDF without preemption
Won’t always work.
Task A CPU utilization 200, task period 1000.
Task B CPU utilization 2, task period 10.
Total CPU utilization is 40%.
At some point in Task A running, Task B will want to start running but task B will
continue running until completion so task B will not meet its deadline.
Page 6 of 12
7. Short answer [6 points, 3 points each]
a) A fellow engineer has a drone using LiPo batteries that she says is draining at 4C and
lasts for 20 minutes. Does that seem reasonable? Briefly explain your answer.
No, even ideally a drain of 4C would last 15 minutes. In reality it will be less than that.
b) What makes a “loadable kernel module” loadable?
You can add it to (and remove it from) the kernel as it is running.
8. Powered by batteries [8 points]
Consider the battery discharge graph to the right.
a) What is the nominal capacity of the battery?
Show your work. [2]
7mA is 53C. So 7mA/53=0.132mAh.
b) If you have a 100A draw from the battery,
about how long will it stay at or above 3V?
Show your work. [3]
Looks like 0.1mA drain give ~0.12mAh. So
1.2 hours (1 hour and 12 minutes).
c) If you have 2 of these batteries in series and you need at least 5V, how long would they last
if the draw is 5mA? Show your work. [3]
With 2 in series we need to stay about 2.5V. So looks like you’d have 0.075mAh capacity. So
about 0.075mAh/5mA = 0.015h = 0.9minutes = 54 seconds.
7mA
Page 7 of 12
Weighing the Options (42 points)
You are interning for a company that makes traditional bathroom weight scales. They operate by
compressing a spring that turns a pointer on a radial dial as shown.
The Problem
The company wants to maintain the original
analog scale appearance, but wants to replace
the spring mechanism with an electronic
system. You propose driving the dial with a
small stepper motor, sensing the weight with a
pressure sensor integrated into the foot bed,
and using an Arduino to perform the weight
measurement and stepper control.
Applying the Stepper Motor
The traditional analog scale dial ranges from 0
to 300 pounds in one pound steps or 360 degrees/300 lbs = 1.2 degrees/lb. Ideally you would find
a stepper motor that has steps of 1.2 degrees, but you can only find cost effective stepper motors
that step every 19.2 degrees. With a little research you discover that it is possible to achieve even
finer steps of rotation using “micro stepping”. With a bit more research you find an integrated
stepper/motor driver that can provide micro stepping and is easy to interface with the Arduino.
The device can provide micro steps in fractions of a power of 2 from ½ to 1/128 of a full 19.2
degree step.
Applying the Pressure Sensor
The pressure sensor is a simple analog device that will provide a voltage that is proportional to
weight. It is scaled to provide 10mv/lb with a maximum capacity of 300 lbs.
The Stepper Motor Controller: AMIS-30543
The stepper motor controller will provide step voltages to the stepper motor on either the rising or falling edges of the control signal NXT depending on how you configure the device.
The direction the motor turns depends on state the configurable pin DIR. Note that DIR must be set before an NXT edge can be asserted. An active high CLR pin is used to reset the controller. The !ERR pin is provided to indicate that an error has occurred in the system and it needs to
be reset and initialized. We will use this pin to generate an interrupt to alert the Arduino and restart the controller.
Micro stepping, NXT transitions and DIR state are all set with a SPI interface. The relevant data
sheets for the device are provided in the reference pack including pinouts, SPI requirements and
register maps. The reference pack also includes all the APIs you will need. Assume the SPI bus runs
at 8 MHz.
Page 8 of 12
Part 1 [10 points]
Provide the connections between the Arduino and stepper motor controller for the SPI interface,
stepper control lines, interrupt and reset. You should also provide power and GND. Add resistors
and capacitors as need. You may use labels to make connections.
Assume the stepper motor connections (MOTxx pins) are made for you. You can ignore the SLA,
!POR/WD, VCP, CPP and CPN pins. You can assume that pressure sensor is connected to analog pin
1 on the Arduino and that the controller uses a supply voltage of 5 volts.
.
Arduino AMIS-30543 4 CLR 5 !ERR 6 DIR 7 NXT 10 CLK 11 DI 12 DO 13 !CS GND GND 5v VDD GND TSTO No connect Other pins
Did not grade for VBB, VCP, CPP,
CPN or bypass capacitor
connections to VDD. Also did not
grade for pull up resistors to
MOSI, MISO or ERR since these
are provided in the Arduino port
declarations.
We didn’t specifically ask for all
relevant passive devices, so we
didn’t take off points for that…
Page 9 of 12
Part 2 [12 points]
Write the initialization function for the stepper motor controller. This should include Arduino SPI
initialization and Arduino pin initialization. Note you should reset the device before communicating
to it to insure SPI communication is working. Set WDEN, WDT, SM, CUR, PWMF, PWMJ, EMC, SLAG,
SLAT and ESM register initialization values to zero.
#include <SPI.h>
void stepper_controler_init(void) {
pinMode(4, OUTPUT); //Clear pin depends on diagram
pinMode(5, INPUT_PULLUP); //ERR pin depends on diagram
pinMode(6, OUTPUT); //DIR pin depends on diagram
pinMode(7, OUTPUT); //NXT pin depends on diagram
//SPI.begin() initializes the following pins 10-13 and sets inactive
//pinMode(13, OUTPUT); //SPI clock, specified in reference
//pinMode(12, OUTPUT); //SPI DI , specified in reference
//pinMode(11, INPUT); //SPI DO, specified in reference
//pinMode(10, OUTPUT); //SPI SS, specified in reference
digitalWrite(4,1); // clear device
digitalWrite(4,0); // release
attachInterrupt(5, restart_stepper_controller, RISING or FALLING);
SPI.begin();
SPISettings my_SPI_setting(8 *10^6 ,MSBFIRST, SPI_MODE0);
SPI.begnTransaction(SPI_settings);
digitalWrite(10,0); //select SPI device
SPI-transfer(0b1000 0000); //write cmd, reg0 0x80
SPI-transfer(0b0000 0000); //WDEN, WDT3, WDT2, WDT1, WDT0, --, --, -- 0x00
SPI-transfer(0b1000 0001); //write cmd, reg1 0x81
SPI-transfer(0b0000 0000); //SM2, SM1, SM0, CUR4, CUR3,CUR2,CUR1,CUR0 0x00
SPI-transfer(0b1000 0010); //write cmd, reg2 0x82
SPI-transfer(0b0000 0000); //DIRCTRL,NXTP, -, -,PWMF,PWMJ,EMC1,EMC0 0x00
//CW motion, moves on rising edge,
SPI-transfer(0b1000 0011); //write cmd, reg3 0x83
SPI-transfer(0b1000 0000); //MOTEN, SLP, SLAG, SLAT, -, -, -, - 0x80
// 1 0
SPI-transfer(0b1000 1001); //write cmd, reg9 0x89
SPI-transfer(0b0000 0001); //-, -, -, -, -, ESM2, ESM1,ESM0 0x01
// 1/16 micro stepping
digitalWrite(10,1); //deselect SPI device
SPI.endTransaction();
Page 10 of 12
Part 3 [15 points]
Write a main function that will initialize the motor controller, read the weight sensor and adjust the
scale accordingly #define NXT 4
#define ERR 2
#define CLR 3
#define CS 10
#define ONE_SIXTEEN 0x1
#define CR0 0x1
SPI_Settings my_settings = SPISettings(8000000, MSBFIRST, SPI_MODE0);
int main() {
//Globals for main (setup and loop)
int last_pounds = 0; //Keep track of old reading
//Setup (Arduino)
setup() {
stepper_controller_init();
//NOTE: The rest assumes this logic was not in init
attachInterrupt(ERR, restart_stepper_controller, FALLING);
//Full SPI Transaction to set 1/16 step (for 1.2/lb)
digitalWrite(CS, LOW);
SPI.beginTransaction(my_settings);
SPI.transfer(0x80 | (CR0 & 0b11111)); //Refer to pg 31 in datasheet
SPI.transfer(ONE_SIXTEEN);
SPI.endTransaction();
digitalWrite(CS, HIGH);
}
//Loop (Arduino)
loop {
int analogVal = analogRead(A1); //From 0 to 1023
float analogToMV = (analogVal / 1023) * 5000;
int curr_pounds = analogToMV / 10; //10 mV per lb
//Now, we configure DIR (either through GPIO or DIRCTL)
if (curr_pounds < last_pounds) {
digitalWrite(DIR, HIGH); //CCW
pulseNxt(last_pounds - curr_pounds);
}
else if (curr_pounds > last_pounds) {
digitalWrite(DIR, LOW); //CW
pulseNxt(curr_pounds - last_pounds);
}
//else we do nothing this iteration
last_pounds = curr_pounds; //Update for next iteration
}
}
/*Pulse Nxt for x number of lbs Assuming microsteps was implemented,
each lb will move nxt 1.2 degrees */
Page 11 of 12
void pulseNxt(int amt) {
for (int i = 0; i < amt; i++) {
digitalWrite(NXT, HIGH);
delay(1);
digitalWrite(NXT, LOW);
delay(1);
}
}
Page 12 of 12
Part 4 [5 points]
Write the interrupt handler that will restart and configure the stepper motor controller.
void restart_stepper_controller(void) {
//Pulse CLR to reset device and internal registers
digitalWrite(CLR, HIGH);
delay(1);
digitalWrite(CLR, LOW);
/*NOTE: If you configured 1/16 in loop() logic,
then its fine to have nothing else here */
//Call init to configure motor for 1/16 step (if done in init)
stepper_controller_init();
//OR configure 1/16 in here (if 1/16 was configured in setup of main)
digitalWrite(CS, LOW);
SPI.beginTransaction(my_settings);
SPI.transfer(0x80 | (CR0 & 0b11111));
SPI.transfer(ONE_SIXTEEN);
SPI.endTransaction();
digitalWrite(CS, HIGH);
}