Give the hardware to a single device driver process. Other processes request a conversion through message passing and never touch its memory-mapped input-output registers. The following is protocol pseudocode for Phōs: its operation names specify their required semantics, rather than asserting an unverified spelling of a particular 2019 C interface. The hardware actions and the request/reply design are fully specified.
Use a FIFO queue of accepted requests, each containing its sender and a per-call token. Bind the device's interrupt to a persistent notification addressed to the driver before any conversion is started. A notification must remain pending if it arrives before the driver next waits; this is the lost-wakeup avoidance requirement. The driver receives both client requests and interrupt notifications in its event loop.
configure sensor and connect its interrupt notification to this process
TEMP_DATARDY := 0
clear stale pending interrupt notification
enable sensor interrupt and interrupt-controller delivery
pending := empty FIFO
active := none
forever:
if active is none and pending is not empty:
active := remove oldest request from pending
TEMP_DATARDY := 0
clear stale pending interrupt notification
TEMP_START := 1
event := wait for a request or persistent interrupt notification
if event is REQUEST(sender, token):
append (sender, token) to pending
if event is sensor interrupt and active is not none:
if TEMP_DATARDY != 0:
value := TEMP_TEMP
TEMP_DATARDY := 0
acknowledge the interrupt through the OS interrupt mechanism
send RESULT(active.token, value) to active.sender
active := noneAfter receiving an idle-time request, the next loop iteration starts its conversion before waiting again. While a conversion is in progress, additional requests join the queue without starting another conversion. A completed reading is copied before its ready flag is cleared, and the next request cannot start until the current result has been delivered. Spurious or stale notifications do not complete a request unless the device's ready register confirms completion.
Clearing old status and notification precedes
TEMP_START; doing so afterwards could erase a very fast completion. The operating system interrupt binding and persistent notification cover completion in the interval between starting the device and entering the wait. Register accesses must use the platform's device-access semantics, including required volatile-qualified objects in C or ordering primitives. Exact initialization and interrupt-connection call names remain an implementation binding, not invented Phōs API calls. The later teaching site's named system is documented separately; it is not used as proof of an identical historical API.[ref]Digital Systems course archive of the University of Oxford. 2018–2019 course record and linked teaching-site description of process/message-based device drivers
Provide a blocking request-reply sensor conversion operation, using synchronous send-and-receive when the system supplies it:
get_temp():
token := a new token for this process's call
reply := request-and-wait(
destination = temperature_driver,
message = REQUEST(self, token),
expected_reply = RESULT(token, value))
return reply.valueHere
request-and-wait means sending the request and remaining ready to accept its matching response; it denotes a protocol action, not a claimed library symbol. Separate blocking send and receive operations are also adequate if they preserve the sender identity and the reply cannot be lost between them. With a synchronous reply, the driver simply waits until this client's receive is ready.The call returns only after the driver has selected this request, issued
TEMP_START, observed completion, read the new value and replied with the matching token. Each call therefore starts its own fresh conversion and returns its own result. It never returns a cached sample or another caller's reply. Local request and response storage belong to the calling process and are not a shared global message buffer.Safety: only the driver accesses the sensor, and
active identifies at most one conversion. Accepted requests are serialized by the FIFO queue. The reply destination and token identify the owner of the resulting sample; no caller can clear another conversion's ready flag or consume another result. Receiving new requests while busy only changes the queue, not the active measurement. These are mutual exclusion and request/result association properties, not timing guesses.Progress: assume each started conversion completes in finite time, the corresponding notification is eventually delivered, the driver and compliant clients are eventually scheduled, and pending message acceptance is fair. A caller remains ready to receive its reply. Every accepted request has finitely many earlier requests in the queue, and later arrivals cannot overtake it. Each earlier request is completed and removed in finite time, so the caller eventually becomes active and receives its own reading. Fair acceptance extends this argument from accepted requests to callers waiting to submit one.
These assumptions are necessary for starvation freedom. A failed sensor, a client that disappears before accepting a synchronous reply, or an unfair scheduler can prevent progress; serialization alone cannot prove otherwise. Under the stated operating model, simultaneous calls are safe and every call completes. A single shared “latest temperature” variable would not establish either a fresh conversion per call or correct reply ownership.
Articles by others on the same topic
There are currently no matching articles.