ECEC 201 · Week 8
Modern Computer: Von Neumann
A register is a byte whose bits mean different things.
Week 8 of 10 · Das Frite
ECEC 201 · Week 8 · In class
A register is a byte whose bits mean different things.
- Masks and shifts pull each field out.
volatiletells the compiler a value can change without the program writing it, and byte order says which byte of a wider value comes first.
ECEC 201 · Week 8 · In class
The station sensor is on the I2C bus the image already enables; the lecture names its device file.
- No device-tree edit.
- Read one register with
ioctlandread, then decode its fields from the datasheet. - Write the mask for each field before the lab.
ECEC 201 · Week 8 · Lecture
A register byte is several fields
| Bits | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| Field | MODE | unused | READY | COUNT | ||||
- This layout is a made-up example, not the station sensor's.
- A mask has ones on the field's bits: MODE is
0xC0, READY0x08, COUNT0x07. - Mask first, then shift the field down to bit 0.
ECEC 201 · Week 8 · Lecture
Masks and shifts in C
#define MODE_MASK 0xC0u
#define MODE_SHIFT 6
#define READY_MASK 0x08u
#define COUNT_MASK 0x07u
unsigned mode = (reg & MODE_MASK) >> MODE_SHIFT;
int ready = (reg & READY_MASK) != 0;
unsigned count = reg & COUNT_MASK;
reg |= READY_MASK; /* set a bit */
reg &= ~READY_MASK; /* clear a bit */
ECEC 201 · Week 8 · Lecture
volatile and byte order
volatiletells the compiler every access really happens: the value can change without the program writing it.- It matters when a pointer reads hardware memory directly. A byte that
read()copied into your buffer is ordinary memory. - A 16-bit register sent as two bytes arrives in the order the datasheet states, not the CPU's order.
- Build it explicitly:
(b[0] << 8) | b[1]when the high byte comes first.
ECEC 201 · Week 8 · Lecture
One register through the I2C device file
/* needs fcntl.h, unistd.h, sys/ioctl.h, linux/i2c-dev.h */
int read_reg(const char *dev, int addr, unsigned char reg)
{
unsigned char val;
int ok = 0, fd = open(dev, O_RDWR);
if (fd < 0)
return -1;
if (ioctl(fd, I2C_SLAVE, addr) == 0 &&
write(fd, ®, 1) == 1)
ok = read(fd, &val, 1) == 1;
close(fd);
return ok ? val : -1;
}
ECEC 201 · Week 8 · Lab
Lab
- On the I2C bus the image already enables, through the device file the lecture names, read one register of the station sensor with `ioctl` and `read`. Do not edit a device tree.
- Decode its fields with masks and shifts, using the sensor's datasheet. Second pass: print the raw byte in binary beside the decoded fields.
ECEC 201 · Week 8 · Lab
Lab (continued)
- Assemble the lab hand-in: The program, the register address, the raw byte, the decoded fields, and the datasheet page you used.
ECEC 201 · Week 8 · Lab
Hand in
The program, the register address, the raw byte, the decoded fields, and the datasheet page you used.
ECEC 201 · Week 8 · Homework
Homework
- From the datasheet, write the bit positions and the mask for each field you will decode, before the lab.
ECEC 201 · Week 8 · Homework
Turn in
The mask table.
ECEC 201 · Week 8 · Read
Read
On the lab site: Module 10, I/O, decodes a bus on an analyser. This week grades a C read of one register and its decoded bits. Stop before the analyser capture.
ECEC 201 · Week 8 · Next
Week 9
A GPIO line is requested from the Linux character device, then set or read.