| .. _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 |