Now we are tuning for efficiency.
- More refactoring.
- Finally add timestamps (kernel jiffies).
- Allow opening a second CAN device (/dev/can1), which configures message objects 1 and 2 to receive the high data rate IMU Accel and Gyro data messages. This allows a second FC thread to operate directly upon large batches of IMU messages at a time, thereby reducing unnecessary context switches. Moving IMU message receipt to the unbuffered objects is OK, since it is not disasterous to lose these, and it does preserve the remainder of the messages received. This change is very rocket specific, hard coding the IMU CAN ids into the driver.
Many reliablility problems were solved:
- Use only the buffered message object 14 for reads. Adapt the read interrupt handler to work better with that object.
- Use only message object 0 for data writes and RTR sends. (All other message objects are unused.) Set the id mask to all care.
- Reset the status register for all types of interrupts, not just errors.
- Simplify the queuing logic between front and back ends of the driver.
Uncanny has been installed and tested on the launch tower and the Flight Computer! In practice, Phase 1 (interruptless) was not completed, and we moved directly into Phase 2.
The main limitation that was uncovered was the inability to detect arbitrary RTR messages. Instead, the Intel chip is designed for the user to set up message buffers with data to send automatically when the matching RTR message is received, without having to involve the higher level software. We have adapted the PIC nodes not to send RTR messages to work around this limitation.
Freenix paper accepted! The paper will be refereed with a final submission deadline of March 25th. The referee is Ralf Nolden (kde.org). Now I'll have to decide whether it's worth a trip to Boston in the summer.
- Unfortunately, work intervened and I had no time to finish the paper or the driver. Also, Ralf had a family emergency and never responded.
Since the paper is supposed to be about developing a working driver, hopefully this will be a kick in the butt to get working on this more regularly. There might be a test on the LTC this weekend at Andrew's house. (In the meantime, small amounts of the interrupt handler have been written.)
Freenix paper submitted! The AbstractFreenix2004 presently.source will be attached to
Not much else has been done on the driver recently. It is in suitable shape to install and test on the LTC, but Ted has been working on the LTC electronics all month.
- Presents one device file per internal CAN I/O buffer. The device minor number selects which buffer. There are fifteen buffers to choose from. The fifteenth is read-only and has a one-element queue.
- Reads and writes fixed length messages (
- Buffers messages read and written to the device, with appropriate interrupt handling
- Device can be opened non-blocking
- Reads and writes cannot be mixed on the same open device, even if opened with
read()has a non-standard implementation to deal with RTR (Request to Transmit a Response) messages. If you fill the buffer with a CAN message ID and the RTR bit set before calling
read(), it will block until the response to that particular RTR message is received. This presumes (incorrectly) that the RTR message was sent successfully by an immediately preceding call to
write(). (At least this is the intent; the driver currently has a bug so that even this won't work.)
- But... you cannot
write()a message with the RTR bit set! (This bug is pervasive, with a lot of cruft in the driver to work around its design decisions.)
select()does not work because the driver does not implement
poll(). This causes any use of select on a CAN device descriptor to return immediately. Code written using select will spend all its time blocking on a 3 second timeout in
The problems outlined above along with the "one device per message object" design decision were found to be too limiting. The current driver is overly general in order to deal with lots of settable parameters, two types of CAN chips, and a multitude of different boards and architectures.
The proposed driver rewrite features:
- Specific to the MOPS 520 board and i82527 chip for simplicity.
- no modparam support; all settings are hardwired
- hardwired IO address range 0x2000-0x20ff, using shared interrupt 10
- bus timing hardwired to 1Mbps, chip clock hardwired to 8MHz
- hardwired major/minor device number 91/0
- no ID filtering
- standard 11-bit IDs only; extended 27-bit IDs not supported
- Presents a single device
/dev/canwhich makes full use of all 15 message objects to allow use of read, write, and RTR messages interspersed on the same
- Device will be exclusive open
- Cleaner implementation
- remove lots of layers of indirection required for hardware abstraction
- no dynamic memory allocation
struct canmsg_tas the data object for
- NOTE fields are changing, see below
writewill write both data and RTR messages
readwill read both data and RTR response messages
- NOTE: using
sucan, we determined that only the buffered message 15 can be configured to receive and detect random RTR messages. The driver will thus always use message 15 when opened for reading CAN messages.
readwill not be sensitive to the incoming data buffer
- NOTE: using
pollimplemented so that
selectworks correctly, at least on read descriptors
- More consistent error codes and plenty of debug messages
Phase 0 user mode chip driver for easier experimentation [DONE 18-Nov-2003]
- Apparently, user applications can access IO ports above 0x400 in x86 Linux systems. The app is required to run as root and make system call
iopl(3)in order to do so. One can then use
inb/outbto twiddle and read the CAN registers. (One could then also disable interrupts, but that would be a Bad Idea.)
- An interactive environment would let us experiment more easily to determine the proper sequence for sending an RTR message.
- I propose a tool
sucanthat takes single letter commands to
- Select message object 1-15
- Set and reset the eight flags in the message CTL registers
- Set the ID of the message
- Set the direction flag in the message CFG register (xmit/recv)
- Enter 0-8 hex data bytes into the message DAT0-7 registers and set DLC in the message CFG register accordingly
- Block waiting to receive a message or finish transmitting a message (w/timeout)
- The tool would do standard chip initialization on startup
- No CAN interrupts enabled!
- The tool would display the state of the current message object after each command.
Phase 1 (started 11 Nov 2003, suitable for low bandwidth commands to LTC):
- New project, Linux device infrastructure (mostly copied from old driver) [DONE]
- From 60 down to 10 source/makefiles
- Committed to
- MOPS/i82527 driver setup [DONE]
- TODO: update chip setup based on
- TODO: update chip setup based on
- File operations merged into
open, closeexclusive open [DONE]
read[DONE, cannot detect RTR messages]
- read and write RTR implementations have been confirmed with
- Spin waiting instead of interrupt handling for simplicity [needs testing]
- poll message registers directly for their status (inefficient, but simple)
- [TODO] timeouts?
- Use the 15 on-chip message objects for read/write/RTR buffering [needs testing]
- reserve some messages (5?) for reading
- Modification of ltc-fc-common library, ltc service as needed [DONE]
- NOTE I am changing the exported
can.hto be closer to the SJA form
- Replace seperate
id, rtr, lenfields with one combined
idfield, same as on the PICs which should allow sharing more headers between firmware and FC level software.
CAN_ID, CAN_RTR, CAN_LENto extract info from a
MAKE_CAN_IDto combine 11-bit ID with RTR and data length
- [TODO] adapt unit test app for the new driver
- [DONE] adapt
ltc-fc-commonlibrary to use the new type definition
- I don't know if anyone noticed, but the old driver had absolutely no support for the
canmsg_t. Does anyone need this field to cross the CAN bus?
- NOTE I am changing the exported
- Goal: successful transmission of single data and RTR messages [DONE]
- Goal: successful receipt of 1 Hz data messages and single RTR responses [DONE]
- Intel chip cannot detect arbitrary RTR messages
- Target completion: 9 Dec 2003
- Mostly written and linking in one evening. Simplification is good!
Phase 2 (suitable for high bandwidth telemetry from FC):
- Interrupt handler
- backside and frontside interrupt code [DONE].
- test throughput and reliablilty [DONE]
poll, so that
selectcan be used [DONE]
procfile system support? (optional)
- show internal performance statistics?
- In-memory read/write queues [DONE]
- Reasonable buffer overflow handling [DONE]
- Reimplementing queue &head-&tail with &head-count makes overflow detection easier. This has been seperately unit tested.
- Goal: successful send/receive of 100(?) Hz data messages [DONE]
- Interspersed reads/writes
- Goal: multiple outstanding RTR requests
- Completed: Sept 5, 2004
-- IanOsgood - Sept 5, 2004
- Our CVS directory for the driver source
i82527.c:lowest level interaction with the chip
i82527.h:chip specific constants and functions
irq.c:interrupt handlers (functions
open(), close(), read(), write(), poll()syscalls
main.c:module infrastructure and driver initialization
can.h:the definition of
- Higher level library to send and receive messages on the CAN bus
- uses the
FIFO_MSGdata type (must be
can_common.h, can_read.c, can_write.c, can_open.c, can_close.c
- uses the
- CanBusLinks has some general links about the CAN protocol
- CanBusIDs lists the structure we chose for our CAN message IDs.
- Specific IDs used on the rocket and launch tower are found in the CVS repository.
- CanBusUtilization talks about the CAN bandwidth requirements on the rocket
- FlightComputerBoard has a large section devoted to setting bus timing for the i82527
- DevelopmentEnvironmentForLv2 has information about how to set up your system to develop the CAN driver
- A primer for developing Linux kernal modules (PDF)
- Knowledgable folk: IanOsgood, BartMassey, , ,
- http://psas.pdx.edu/view/WEB/FlightComputer/Intel 82527 Architecture.pdf
- http://psas.pdx.edu/view/WEB/FlightComputer/Intel 82527 CAN Controller.pdf
-- IanOsgood - 03 Oct 2003