e7436f7c55
This code used a sys_mem_pool directly. Use a new-style heap instead to do the same thing. (Note that the usage is a little specious -- it allocates from the heap but doesn't appear to fill or check any data therein, just that the heap memory can be copied from the two memory domains. It's unclear exactly what this is trying to demonstrate and we might want to improve the sample to do something less trivial.) Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
104 lines
4.3 KiB
ReStructuredText
104 lines
4.3 KiB
ReStructuredText
.. _userspace_prod_consumer:
|
|
|
|
Producer/consumer
|
|
=================
|
|
|
|
This is a sample application that exercises some user mode concepts.
|
|
|
|
Overview
|
|
********
|
|
|
|
Consider a "sample driver" which gets incoming data from some unknown source
|
|
and generates interrupts with pointers to this data. The application needs
|
|
to perform some processing on this data and then write the processed data
|
|
back to the driver.
|
|
|
|
The goal here is to demonstrate:
|
|
|
|
- Multiple logical applications, each with their own memory domain
|
|
- Creation of a sys_heap and assignment to a memory partition
|
|
- Use of APIs like ``k_queue_alloc_append()`` which require thread resource
|
|
pools to be configured
|
|
- Management of permissions for kernel objects and drivers
|
|
- Show how application-specific system calls are defined
|
|
- Show IPC between ISR and application (using ``k_msgq``) and
|
|
application-to-application IPC (using ``k_queue``)
|
|
- Show how to create application-specific system calls
|
|
|
|
In this example, we have an Application A whose job is to talk to the
|
|
driver, buffer incoming data, and write it back once processed by
|
|
Application B.
|
|
|
|
Application B simply processes the data. Let's pretend this data is
|
|
untrusted and possibly malicious, so Application B is sandboxed from
|
|
everything else, with just two queues for sending/receiving data items.
|
|
|
|
The control loop is as follows:
|
|
|
|
- Sample driver issues interrupts, invoking its associated callback
|
|
function with a fixed-sized data payload.
|
|
- App A callback function, in supervisor mode, places the data payload
|
|
into a message queue.
|
|
- App A monitor thread in user mode waits for data in the message queue.
|
|
When it wakes up, copy the data payload into a buffer allocated out
|
|
of the shared memory pool, and enqueue this data into a ``k_queue`` being
|
|
monitored by application B.
|
|
- Application B processing thread waits on new items in the queue. It
|
|
then processes the data in-place, and after it's finished it places
|
|
the processed data into another queue to be written back to the driver.
|
|
- Application A writeback thread monitors the outgoing data queue for
|
|
new items containing processed data. As it gets them it will write
|
|
such data back to the driver and free the buffer.
|
|
|
|
We also demonstrate application-defined system calls, in the form of
|
|
the ``magic_cookie()`` function.
|
|
|
|
Sample Output
|
|
*************
|
|
|
|
.. code-block:: console
|
|
|
|
I:APP A partition: 0x00110000 4096
|
|
I:Shared partition: 0x0010e000 4096
|
|
I:sample_driver_foo_isr: param=0x00147078 count=0
|
|
I:monitor thread got data payload #0
|
|
I:sample_driver_foo_isr: param=0x00147078 count=1
|
|
I:monitor thread got data payload #1
|
|
I:sample_driver_foo_isr: param=0x00147078 count=2
|
|
I:monitor thread got data payload #2
|
|
I:sample_driver_foo_isr: param=0x00147078 count=3
|
|
I:monitor thread got data payload #3
|
|
I:sample_driver_foo_isr: param=0x00147078 count=4
|
|
I:monitor thread got data payload #4
|
|
I:processing payload #1 complete
|
|
I:writing processed data blob back to the sample device
|
|
I:sample_driver_foo_isr: param=0x00147078 count=5
|
|
I:monitor thread got data payload #5
|
|
I:processing payload #2 complete
|
|
I:writing processed data blob back to the sample device
|
|
I:sample_driver_foo_isr: param=0x00147078 count=6
|
|
I:monitor thread got data payload #6
|
|
I:processing payload #3 complete
|
|
I:writing processed data blob back to the sample device
|
|
I:sample_driver_foo_isr: param=0x00147078 count=7
|
|
I:monitor thread got data payload #7
|
|
I:processing payload #4 complete
|
|
I:writing processed data blob back to the sample device
|
|
I:sample_driver_foo_isr: param=0x00147078 count=8
|
|
I:monitor thread got data payload #8
|
|
I:processing payload #5 complete
|
|
I:writing processed data blob back to the sample device
|
|
I:sample_driver_foo_isr: param=0x00147078 count=9
|
|
I:monitor thread got data payload #9
|
|
I:processing payload #6 complete
|
|
I:writing processed data blob back to the sample device
|
|
I:processing payload #7 complete
|
|
I:writing processed data blob back to the sample device
|
|
I:processing payload #8 complete
|
|
I:writing processed data blob back to the sample device
|
|
I:processing payload #9 complete
|
|
I:writing processed data blob back to the sample device
|
|
I:processing payload #10 complete
|
|
I:writing processed data blob back to the sample device
|
|
I:SUCCESS
|