userspace: sample app domain applications
Added a sample using the app_memory submodule to protect memory used by three threads. Signed-off-by: Shawn Mosley <smmosle@tycho.nsa.gov>
This commit is contained in:
parent
b6468999e4
commit
26c51c43d0
8 changed files with 625 additions and 0 deletions
8
samples/basic/userspace/shared_mem/CMakeLists.txt
Normal file
8
samples/basic/userspace/shared_mem/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
cmake_minimum_required(VERSION 3.9.1)
|
||||||
|
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
|
||||||
|
project(NONE)
|
||||||
|
|
||||||
|
FILE(GLOB app_sources src/*.c)
|
||||||
|
target_sources(app PRIVATE ${app_sources})
|
||||||
|
#add_definitions( -DALTMSG)
|
||||||
|
#add_definitions( -DDBUG)
|
58
samples/basic/userspace/shared_mem/README.rst
Normal file
58
samples/basic/userspace/shared_mem/README.rst
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
.. _userspace_protected_memory:
|
||||||
|
|
||||||
|
Userspace Protected Memory
|
||||||
|
##########################
|
||||||
|
|
||||||
|
Overview
|
||||||
|
********
|
||||||
|
This sample is an example of running multiple threads assigned
|
||||||
|
unique memory domains with protected partitions. The
|
||||||
|
application uses memory partitioning with a sample algorithm
|
||||||
|
simulating an enigma-like machine, but the implementation of the
|
||||||
|
machine has not been validated and should not be used for any
|
||||||
|
actual security purposes.
|
||||||
|
|
||||||
|
Requirments
|
||||||
|
***********
|
||||||
|
|
||||||
|
The sample is dependent on the subsystem app_memory, and it will
|
||||||
|
not run on boards that do not support the subsystem. The sample
|
||||||
|
was tested on the following boards qemu_x86,frdm_k64, an 96b_carbon.
|
||||||
|
|
||||||
|
Building and Running
|
||||||
|
********************
|
||||||
|
|
||||||
|
This example will only cover the qemu_x86 board, since the sample
|
||||||
|
just prints text to a console.
|
||||||
|
|
||||||
|
.. zephyr-app-commands::
|
||||||
|
:zephyr-app: samples/basic/userspace/shared_mem
|
||||||
|
:board: qemu_x86
|
||||||
|
:goals: build run
|
||||||
|
:compact:
|
||||||
|
|
||||||
|
After starting, the console will display multiple starting messages
|
||||||
|
followed by two series of repeating messages. The repeating messages
|
||||||
|
are the input and output of the enigma-like machine. The second
|
||||||
|
message is the output of the first mesessage, and the resulting
|
||||||
|
output is the first message without spaces. The two messages are
|
||||||
|
marked as 1 and 1' respectively.
|
||||||
|
|
||||||
|
Two definitions can be inserted to change the wheel settings and print
|
||||||
|
the state information. To enable the definitions uncomment the last
|
||||||
|
two lines in CMakelists.txt.
|
||||||
|
|
||||||
|
Functionality
|
||||||
|
*************
|
||||||
|
The PT thread sends a message followed by the encrypted version of the
|
||||||
|
message after sleeping. To send the message the PT thread checks a
|
||||||
|
flag, and if it is clear, writes the message to a buffer shared with
|
||||||
|
the encrypt thread. After writing the buffer, the flag is set. The
|
||||||
|
encrypt thread copies the memory from the common buffer into the
|
||||||
|
encrypted thead's private memory when the flag is set and then clears
|
||||||
|
the flag. Once the encrypted thread receives the text string, it
|
||||||
|
performs a simulation of the enigma machine to produce cypher text(CT).
|
||||||
|
The CT is copied to a shared memory partition connecting to the third
|
||||||
|
thread. The third thread prints the CT to the console with a banner
|
||||||
|
denoting the content as CYPHER TEXT.
|
||||||
|
|
3
samples/basic/userspace/shared_mem/prj.conf
Normal file
3
samples/basic/userspace/shared_mem/prj.conf
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
CONFIG_USERSPACE=y
|
||||||
|
CONFIG_APPLICATION_MEMORY=n
|
||||||
|
CONFIG_APP_SHARED_MEM=y
|
17
samples/basic/userspace/shared_mem/sample.yaml
Normal file
17
samples/basic/userspace/shared_mem/sample.yaml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
sample:
|
||||||
|
description: userspace memory domain protection
|
||||||
|
example application
|
||||||
|
name: protected memory
|
||||||
|
platforms: all
|
||||||
|
common:
|
||||||
|
tags: samples
|
||||||
|
harness: console
|
||||||
|
harness_config:
|
||||||
|
type: one_line
|
||||||
|
regex:
|
||||||
|
- "MSG"
|
||||||
|
tests:
|
||||||
|
kernel.memory_protection.userspace:
|
||||||
|
filter: CONFIG_ARCH_HAS_USERSPACE
|
||||||
|
tags: userspace samples
|
||||||
|
|
161
samples/basic/userspace/shared_mem/src/enc.c
Normal file
161
samples/basic/userspace/shared_mem/src/enc.c
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
* enc.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a model of the enigma hardware as remembered from
|
||||||
|
* a description read around ten years prior. The model has
|
||||||
|
* not been tested or validated as cryptographically secure.
|
||||||
|
* Furthermore the author intentionally did not validate the
|
||||||
|
* model against published descriptions of the enigma. The
|
||||||
|
* only test completed was to set the wheels to a known
|
||||||
|
* position and insert a pt string of text into the function.
|
||||||
|
* The output was recorded as ct. The wheels were reset to the
|
||||||
|
* original start position, and the recorded ct was inserted
|
||||||
|
* into the function. The output was compared to the original
|
||||||
|
* pt text and matched. The result of the test matched the
|
||||||
|
* expected outcome, but it does not validate the algorithm
|
||||||
|
* meets any security requirments.
|
||||||
|
*
|
||||||
|
* **********************************************************
|
||||||
|
*
|
||||||
|
* DO NOT USE IN PRODUCTION CODE AS A SECURITY FEATURE
|
||||||
|
*
|
||||||
|
* **********************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "enc.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* for a pt character encrypt a ct character and update wheels
|
||||||
|
* Each wheel must be indexed into and out of the wheel arrays
|
||||||
|
* this process is based on a absolute index of input characters
|
||||||
|
* and the reflector.
|
||||||
|
* Note: the output of wheel arrays are added to WHEEL_SIZE
|
||||||
|
* to prevent a negative index when subtracting the iw value.
|
||||||
|
* The printk lines have been left in to inspect operations
|
||||||
|
* of the enigma simulation. simply add the definition DBUG
|
||||||
|
* to enable the detailed messages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
char enig_enc(char pt)
|
||||||
|
{
|
||||||
|
short tmpIndex;
|
||||||
|
char ct;
|
||||||
|
#ifdef DBUG
|
||||||
|
printk("\nEE PT: %c, %02x\n", pt, pt);
|
||||||
|
printk("Index: %d, %d, %d\n", IW1, IW2, IW3);
|
||||||
|
#endif
|
||||||
|
tmpIndex = char_to_index(pt);
|
||||||
|
#ifdef DBUG
|
||||||
|
printk("EE : %02x\n", tmpIndex);
|
||||||
|
#endif
|
||||||
|
/* if error return */
|
||||||
|
if (tmpIndex == -1)
|
||||||
|
return (char)0xFF;
|
||||||
|
tmpIndex = (W1[IMOD(IW1, tmpIndex)] + WHEEL_SIZE - IW1) % WHEEL_SIZE;
|
||||||
|
#ifdef DBUG
|
||||||
|
printk("EE i1: %02x\n", tmpIndex);
|
||||||
|
#endif
|
||||||
|
tmpIndex = (W2[IMOD(IW2, tmpIndex)] + WHEEL_SIZE - IW2) % WHEEL_SIZE;
|
||||||
|
#ifdef DBUG
|
||||||
|
printk("EE i2: %02x\n", tmpIndex);
|
||||||
|
#endif
|
||||||
|
tmpIndex = (W3[IMOD(IW3, tmpIndex)] + WHEEL_SIZE - IW3) % WHEEL_SIZE;
|
||||||
|
#ifdef DBUG
|
||||||
|
printk("EE i3: %02x\n", tmpIndex);
|
||||||
|
#endif
|
||||||
|
tmpIndex = R[tmpIndex];
|
||||||
|
#ifdef DBUG
|
||||||
|
printk("EE r: %02x\n", tmpIndex);
|
||||||
|
#endif
|
||||||
|
tmpIndex = (W3R[IMOD(IW3, tmpIndex)] + WHEEL_SIZE - IW3) % WHEEL_SIZE;
|
||||||
|
#ifdef DBUG
|
||||||
|
printk("EE i3: %02x\n", tmpIndex);
|
||||||
|
#endif
|
||||||
|
tmpIndex = (W2R[IMOD(IW2, tmpIndex)] + WHEEL_SIZE - IW2) % WHEEL_SIZE;
|
||||||
|
#ifdef DBUG
|
||||||
|
printk("EE i2: %02x\n", tmpIndex);
|
||||||
|
#endif
|
||||||
|
tmpIndex = (W1R[IMOD(IW1, tmpIndex)] + WHEEL_SIZE - IW1) % WHEEL_SIZE;
|
||||||
|
#ifdef DBUG
|
||||||
|
printk("EE i1: %02x\n", tmpIndex);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ct = index_to_char(tmpIndex);
|
||||||
|
#ifdef DBUG
|
||||||
|
printk("EE CT: %02x\n", ct);
|
||||||
|
#endif
|
||||||
|
/* test ct value or just return error ? */
|
||||||
|
update_wheel_index();
|
||||||
|
return ct;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* calc reverse path for wheel
|
||||||
|
* this simplifies the reverse path calculation
|
||||||
|
* Return: 1:ok -1 error
|
||||||
|
*/
|
||||||
|
int calc_rev_wheel(BYTE *wheel, BYTE *backpath)
|
||||||
|
{
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < WHEEL_SIZE; i++) {
|
||||||
|
if (wheel[i] >= WHEEL_SIZE || wheel[i] < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
backpath[wheel[i]] = i;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* convert a-z to 0-25
|
||||||
|
*/
|
||||||
|
short char_to_index(char c)
|
||||||
|
{
|
||||||
|
if (c < 'a' || c > 'z') {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return (short)(c - 'a');
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* convert from a index 0-25 to a-z
|
||||||
|
*/
|
||||||
|
char index_to_char(short i)
|
||||||
|
{
|
||||||
|
if (i < 0 || i > 25) {
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
return (char)((short)'a' + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* basic update to wheels based on full rotation
|
||||||
|
* of prior wheel. This could be modified to change
|
||||||
|
* the direction of rotation or order of updates
|
||||||
|
*/
|
||||||
|
void update_wheel_index(void)
|
||||||
|
{
|
||||||
|
IW1++;
|
||||||
|
if (IW1 >= WHEEL_SIZE) {
|
||||||
|
IW1 %= WHEEL_SIZE;
|
||||||
|
IW2++;
|
||||||
|
}
|
||||||
|
if (IW2 >= WHEEL_SIZE) {
|
||||||
|
IW2 %= WHEEL_SIZE;
|
||||||
|
IW3++;
|
||||||
|
}
|
||||||
|
if (IW3 >= WHEEL_SIZE) {
|
||||||
|
IW3 %= WHEEL_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
37
samples/basic/userspace/shared_mem/src/enc.h
Normal file
37
samples/basic/userspace/shared_mem/src/enc.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/* enc.h */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef ENC_H
|
||||||
|
#define ENC_H
|
||||||
|
|
||||||
|
#include <misc/printk.h>
|
||||||
|
|
||||||
|
#define WHEEL_SIZE 26
|
||||||
|
#define IMOD(a, b) ((a + b) % WHEEL_SIZE)
|
||||||
|
|
||||||
|
#ifndef BYTE
|
||||||
|
#define BYTE unsigned char
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void update_wheel_index(void);
|
||||||
|
char index_to_char(short i);
|
||||||
|
short char_to_index(char c);
|
||||||
|
int calc_rev_wheel(BYTE *wheel, BYTE *backpath);
|
||||||
|
char enig_enc(char pt);
|
||||||
|
|
||||||
|
extern BYTE W1[26];
|
||||||
|
extern BYTE W2[26];
|
||||||
|
extern BYTE W3[26];
|
||||||
|
extern BYTE R[26];
|
||||||
|
extern BYTE W1R[26];
|
||||||
|
extern BYTE W2R[26];
|
||||||
|
extern BYTE W3R[26];
|
||||||
|
extern int IW1;
|
||||||
|
extern int IW2;
|
||||||
|
extern int IW3;
|
||||||
|
|
||||||
|
#endif
|
280
samples/basic/userspace/shared_mem/src/main.c
Normal file
280
samples/basic/userspace/shared_mem/src/main.c
Normal file
|
@ -0,0 +1,280 @@
|
||||||
|
/* main.c */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Basic example of userspace thread protected memory
|
||||||
|
*
|
||||||
|
* NOTE: The encryption algorithim is unverified and
|
||||||
|
* based on a 1930's erra piece of hardware.
|
||||||
|
* DO NOT USE THIS CODE FOR SECURITY
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "main.h"
|
||||||
|
#include "enc.h"
|
||||||
|
/* the following definition name prefix is to avoid a conflict */
|
||||||
|
#define SAMP_BLOCKSIZE 50
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The memory partitions have been named to simplify
|
||||||
|
* the definition of variables. A possible alternative
|
||||||
|
* is using one source file per thread and implementing
|
||||||
|
* a objcopy to rename the data and bss section for the
|
||||||
|
* thread to the partiotion name.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* prepare the memory partition structures */
|
||||||
|
FOR_EACH(appmem_partition, part0, part1, part2, part3, part4);
|
||||||
|
/* prepare the memory domain structures */
|
||||||
|
FOR_EACH(appmem_domain, dom0, dom1, dom2);
|
||||||
|
/* each variable starts with a name defined in main.h
|
||||||
|
* the names are symbolic for the memory partitions
|
||||||
|
* purpose.
|
||||||
|
*/
|
||||||
|
_app_red_b BYTE fBUFIN;
|
||||||
|
_app_red_b BYTE BUFIN[63];
|
||||||
|
|
||||||
|
_app_blk_b BYTE fBUFOUT;
|
||||||
|
_app_blk_b BYTE BUFOUT[63];
|
||||||
|
|
||||||
|
/* declare and set wheel and reflector */
|
||||||
|
/* To use add definition ALTMSG */
|
||||||
|
#ifdef ALTMSG
|
||||||
|
_app_enc_d BYTE W1[26] = START_WHEEL;
|
||||||
|
#else
|
||||||
|
_app_enc_d BYTE W1[26] = START_WHEEL2;
|
||||||
|
#endif
|
||||||
|
_app_enc_d BYTE W2[26] = START_WHEEL;
|
||||||
|
_app_enc_d BYTE W3[26] = START_WHEEL;
|
||||||
|
_app_enc_d BYTE R[26] = REFLECT;
|
||||||
|
|
||||||
|
_app_enc_b int IW1;
|
||||||
|
_app_enc_b int IW2;
|
||||||
|
_app_enc_b int IW3;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* calculated by the enc thread at init and when the wheels
|
||||||
|
* change.
|
||||||
|
*/
|
||||||
|
_app_enc_b BYTE W1R[26];
|
||||||
|
_app_enc_b BYTE W2R[26];
|
||||||
|
_app_enc_b BYTE W3R[26];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sync threads
|
||||||
|
*/
|
||||||
|
K_SEM_DEFINE(allforone, 0, 3);
|
||||||
|
|
||||||
|
__kernel struct k_thread enc_thread;
|
||||||
|
K_THREAD_STACK_DEFINE(enc_stack, STACKSIZE);
|
||||||
|
|
||||||
|
__kernel struct k_thread pt_thread;
|
||||||
|
K_THREAD_STACK_DEFINE(pt_stack, STACKSIZE);
|
||||||
|
|
||||||
|
__kernel struct k_thread ct_thread;
|
||||||
|
K_THREAD_STACK_DEFINE(ct_stack, STACKSIZE);
|
||||||
|
|
||||||
|
_app_enc_d char encMSG[] = "ENC!\n";
|
||||||
|
_app_enc_d int enc_state = 1;
|
||||||
|
_app_enc_b char enc_pt[50]; /* Copy form shared pt */
|
||||||
|
_app_enc_b char enc_ct[50]; /* Copy to shared ct */
|
||||||
|
|
||||||
|
_app_user_d char ptMSG[] = "PT: message to encrypt\n";
|
||||||
|
|
||||||
|
/* encrypted message when W1 = START_WHEEL */
|
||||||
|
/* to use add definition ALTMSG */
|
||||||
|
#ifdef ALTMSG
|
||||||
|
_app_user_d char ptMSG2[] = "nfttbhfspfmdqzos\n";
|
||||||
|
#else
|
||||||
|
/* encrypted message when W1 = START_WHEEL2 */
|
||||||
|
_app_user_d char ptMSG2[] = "ofttbhfspgmeqzos\n";
|
||||||
|
#endif
|
||||||
|
_app_ct_d char ctMSG[] = "CT!\n";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
k_tid_t tPT, tENC, tCT;
|
||||||
|
|
||||||
|
k_thread_access_grant(k_current_get(), &allforone, NULL);
|
||||||
|
/* initialize the partition structures */
|
||||||
|
FOR_EACH(appmem_init_part, part0, part1, part2, part3, part4);
|
||||||
|
|
||||||
|
printk("init partitions complete\n");
|
||||||
|
appmem_init_app_memory();
|
||||||
|
printk("init app memory complete\n");
|
||||||
|
/*
|
||||||
|
* create an enc thread init the memory domain and add partitions
|
||||||
|
* then add the thread to the domain.
|
||||||
|
*/
|
||||||
|
tENC = k_thread_create(&enc_thread, enc_stack, STACKSIZE,
|
||||||
|
(k_thread_entry_t)enc, NULL, NULL, NULL,
|
||||||
|
-1, K_USER,
|
||||||
|
K_FOREVER);
|
||||||
|
k_thread_access_grant(tENC, &allforone, NULL);
|
||||||
|
/* use K_FOREVER followed by k_thread_start*/
|
||||||
|
printk("ENC Thread Created %08X\n", (unsigned int) tENC);
|
||||||
|
appmem_init_domain_dom1(part2);
|
||||||
|
printk("init domain complete\n");
|
||||||
|
appmem_add_part_dom1(part1);
|
||||||
|
appmem_add_part_dom1(part3);
|
||||||
|
printk("Partitions added to dom1\n");
|
||||||
|
appmem_add_thread_dom1(tENC);
|
||||||
|
printk("dom1 Created\n");
|
||||||
|
|
||||||
|
|
||||||
|
tPT = k_thread_create(&pt_thread, pt_stack, STACKSIZE,
|
||||||
|
(k_thread_entry_t)pt, NULL, NULL, NULL,
|
||||||
|
-1, K_USER,
|
||||||
|
K_FOREVER);
|
||||||
|
k_thread_access_grant(tPT, &allforone, NULL);
|
||||||
|
printk("PT Thread Created %08X\n", (unsigned int) tPT);
|
||||||
|
appmem_init_domain_dom0(part0);
|
||||||
|
appmem_add_part_dom0(part1);
|
||||||
|
appmem_add_thread_dom0(tPT);
|
||||||
|
printk("dom0 Created\n");
|
||||||
|
|
||||||
|
tCT = k_thread_create(&ct_thread, ct_stack, STACKSIZE,
|
||||||
|
(k_thread_entry_t)ct, NULL, NULL, NULL,
|
||||||
|
-1, K_USER,
|
||||||
|
K_FOREVER);
|
||||||
|
k_thread_access_grant(tCT, &allforone, NULL);
|
||||||
|
printk("CT Thread Created %08X\n", (unsigned int) tCT);
|
||||||
|
appmem_init_domain_dom2(part4);
|
||||||
|
appmem_add_part_dom2(part3);
|
||||||
|
appmem_add_thread_dom2(tCT);
|
||||||
|
printk("dom2 Created\n");
|
||||||
|
|
||||||
|
k_thread_start(&enc_thread);
|
||||||
|
/* need to start all three threads. let enc go first to perform init step */
|
||||||
|
|
||||||
|
printk("ENC thread started\n");
|
||||||
|
k_thread_start(&pt_thread);
|
||||||
|
printk("PT thread started\n");
|
||||||
|
|
||||||
|
k_thread_start(&ct_thread);
|
||||||
|
k_sem_give(&allforone);
|
||||||
|
printk("CT thread started\n");
|
||||||
|
k_thread_abort(k_current_get());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The enc thread.
|
||||||
|
* Function: initialize the the simulation of the wheels.
|
||||||
|
* Copy memory from pt thread and encrypt to a local buffer
|
||||||
|
* then copy to the ct thread.
|
||||||
|
*/
|
||||||
|
void enc(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
int index, index_out;
|
||||||
|
if (enc_state == 1) {
|
||||||
|
fBUFIN = 0; /* clear flags */
|
||||||
|
fBUFOUT = 0;
|
||||||
|
calc_rev_wheel((BYTE *) &W1, (BYTE *)&W1R);
|
||||||
|
calc_rev_wheel((BYTE *) &W2, (BYTE *)&W2R);
|
||||||
|
calc_rev_wheel((BYTE *) &W3, (BYTE *)&W3R);
|
||||||
|
IW1 = 0;
|
||||||
|
IW2 = 0;
|
||||||
|
IW3 = 0;
|
||||||
|
enc_state = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
k_sem_take(&allforone, K_FOREVER);
|
||||||
|
if (fBUFIN == 1) { /* 1 is process text */
|
||||||
|
printk("ENC Thread Received Data\n");
|
||||||
|
/* copy message form shared mem and clear flag */
|
||||||
|
memcpy(&enc_pt, BUFIN, SAMP_BLOCKSIZE);
|
||||||
|
printk("ENC PT MSG: %s\n", (char *)&enc_pt);
|
||||||
|
fBUFIN = 0;
|
||||||
|
/* reset wheel: probably better as a flag option */
|
||||||
|
IW1 = 7;
|
||||||
|
IW2 = 2;
|
||||||
|
IW3 = 3;
|
||||||
|
/* encode */
|
||||||
|
memset(&enc_ct, 0, SAMP_BLOCKSIZE); /* clear memory */
|
||||||
|
for (index = 0, index_out = 0; index < SAMP_BLOCKSIZE; index++) {
|
||||||
|
if (enc_pt[index] == '\0') {
|
||||||
|
enc_ct[index_out] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (enc_pt[index] >= 'a' && enc_pt[index] <= 'z') {
|
||||||
|
enc_ct[index_out] = (BYTE)enig_enc((BYTE) enc_pt[index]);
|
||||||
|
index_out++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* test for CT flag */
|
||||||
|
while (fBUFOUT != 0) {
|
||||||
|
k_sleep(100);
|
||||||
|
}
|
||||||
|
/* ct thread has cleared the buffer */
|
||||||
|
memcpy(&BUFOUT, &enc_ct, SAMP_BLOCKSIZE);
|
||||||
|
fBUFOUT = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
k_sem_give(&allforone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the pt function pushes data to the enc thread.
|
||||||
|
* It can be extended to receive data from a serial port
|
||||||
|
* and pass the data to enc
|
||||||
|
*/
|
||||||
|
void pt(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
k_sleep(2000);
|
||||||
|
while (1) {
|
||||||
|
k_sem_take(&allforone, K_FOREVER);
|
||||||
|
if (fBUFIN == 0) { /* send message to encode */
|
||||||
|
printk("\nPT Sending Message 1\n");
|
||||||
|
memset(&BUFIN, 0, SAMP_BLOCKSIZE);
|
||||||
|
memcpy(&BUFIN, &ptMSG, sizeof(ptMSG));
|
||||||
|
/* strlen should not be used if user provided data, needs a max length set */
|
||||||
|
fBUFIN = 1;
|
||||||
|
}
|
||||||
|
k_sem_give(&allforone);
|
||||||
|
k_sem_take(&allforone, K_FOREVER);
|
||||||
|
if (fBUFIN == 0) { /* send message to decode */
|
||||||
|
printk("\nPT Sending Message 1'\n");
|
||||||
|
memset(&BUFIN, 0, SAMP_BLOCKSIZE);
|
||||||
|
memcpy(&BUFIN, &ptMSG2, sizeof(ptMSG2));
|
||||||
|
fBUFIN = 1;
|
||||||
|
}
|
||||||
|
k_sem_give(&allforone);
|
||||||
|
k_sleep(5000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CT waits for fBUFOUT = 1 then copies
|
||||||
|
* the message clears the flag and prints
|
||||||
|
*/
|
||||||
|
void ct(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
char tbuf[60];
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
k_sem_take(&allforone, K_FOREVER);
|
||||||
|
if (fBUFOUT == 1) {
|
||||||
|
printk("CT Thread Receivedd Message\n");
|
||||||
|
memset(&tbuf, 0, sizeof(tbuf));
|
||||||
|
memcpy(&tbuf, BUFOUT, SAMP_BLOCKSIZE);
|
||||||
|
fBUFOUT = 0;
|
||||||
|
printk("CT MSG: %s\n", (char *)&tbuf);
|
||||||
|
}
|
||||||
|
k_sem_give(&allforone);
|
||||||
|
}
|
||||||
|
}
|
61
samples/basic/userspace/shared_mem/src/main.h
Normal file
61
samples/basic/userspace/shared_mem/src/main.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/* main.h */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MAIN_H
|
||||||
|
#define MAIN_H
|
||||||
|
|
||||||
|
#include <zephyr.h>
|
||||||
|
#include <misc/printk.h>
|
||||||
|
#include <kernel_structs.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <app_memory/app_memdomain.h>
|
||||||
|
#include <misc/util.h>
|
||||||
|
|
||||||
|
#if defined(CONFIG_ARC)
|
||||||
|
#include <arch/arc/v2/mpu/arc_core_mpu.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void enc(void);
|
||||||
|
void pt(void);
|
||||||
|
void ct(void);
|
||||||
|
|
||||||
|
#define _app_user_d _app_dmem(part0)
|
||||||
|
#define _app_user_b _app_bmem(part0)
|
||||||
|
|
||||||
|
#define _app_red_d _app_dmem(part1)
|
||||||
|
#define _app_red_b _app_bmem(part1)
|
||||||
|
|
||||||
|
#define _app_enc_d _app_dmem(part2)
|
||||||
|
#define _app_enc_b _app_bmem(part2)
|
||||||
|
|
||||||
|
#define _app_blk_d _app_dmem(part3)
|
||||||
|
#define _app_blk_b _app_bmem(part3)
|
||||||
|
|
||||||
|
#define _app_ct_d _app_dmem(part4)
|
||||||
|
#define _app_ct_b _app_bmem(part4)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constant
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define STACKSIZE 1024
|
||||||
|
|
||||||
|
#define PRIORITY 7
|
||||||
|
|
||||||
|
#define BYTE unsigned char
|
||||||
|
|
||||||
|
|
||||||
|
#define START_WHEEL {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, \
|
||||||
|
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}
|
||||||
|
#define START_WHEEL2 {6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, \
|
||||||
|
17, 18, 19, 20, 21, 22, 23, 24, 25, 5, 0, 4, 1, 3, 2}
|
||||||
|
#define REFLECT {1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, \
|
||||||
|
15, 14, 17, 16, 19, 18, 21, 20, 23, 22, 25, 24}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
Loading…
Add table
Add a link
Reference in a new issue