ipm: add demo code for inter-processor mailboxes
Migrated from internal repository. Run "make flash" for each on the same Arduino 101 device. Origin: Original code, Zephyr "hello world" used as a starting point Change-Id: I3fdeed6b7e85ad703983c2674e265c85a365ce5b Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
572e052379
commit
8554331b94
10 changed files with 310 additions and 0 deletions
6
samples/ipm/ipm_demo_arc/Makefile
Normal file
6
samples/ipm/ipm_demo_arc/Makefile
Normal file
|
@ -0,0 +1,6 @@
|
|||
BOARD ?= arduino_101_sss
|
||||
VPFILE = prj.mdef
|
||||
KERNEL_TYPE = nano
|
||||
CONF_FILE = prj.conf
|
||||
|
||||
include ${ZEPHYR_BASE}/Makefile.inc
|
10
samples/ipm/ipm_demo_arc/prj.conf
Normal file
10
samples/ipm/ipm_demo_arc/prj.conf
Normal file
|
@ -0,0 +1,10 @@
|
|||
CONFIG_STDOUT_CONSOLE=y
|
||||
CONFIG_KERNEL_BIN_NAME="arc"
|
||||
CONFIG_PRINTK=y
|
||||
CONFIG_IPM=y
|
||||
CONFIG_IPM_QUARK_SE=y
|
||||
CONFIG_IPM_CONSOLE_SENDER=y
|
||||
CONFIG_CONSOLE=y
|
||||
CONFIG_SERIAL=n
|
||||
CONFIG_NS16550=n
|
||||
CONFIG_NANO_TIMEOUTS=y
|
11
samples/ipm/ipm_demo_arc/prj.mdef
Normal file
11
samples/ipm/ipm_demo_arc/prj.mdef
Normal file
|
@ -0,0 +1,11 @@
|
|||
% Application : Hello demo
|
||||
|
||||
% TASK NAME PRIO ENTRY STACK GROUPS
|
||||
% ==================================
|
||||
TASK TASKA 7 taskA 2048 [EXE]
|
||||
TASK TASKB 7 taskB 2048 [EXE]
|
||||
|
||||
% SEMA NAME
|
||||
% =============
|
||||
SEMA TASKASEM
|
||||
SEMA TASKBSEM
|
5
samples/ipm/ipm_demo_arc/src/Makefile
Normal file
5
samples/ipm/ipm_demo_arc/src/Makefile
Normal file
|
@ -0,0 +1,5 @@
|
|||
ccflags-y += ${PROJECTINCLUDE} \
|
||||
-I$(srctree)/include/drivers \
|
||||
-I$(srctree)/drivers -I$(srctree)/arch/arc
|
||||
|
||||
obj-y = hello.o
|
102
samples/ipm/ipm_demo_arc/src/hello.c
Normal file
102
samples/ipm/ipm_demo_arc/src/hello.c
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2014 Wind River Systems, Inc.
|
||||
* Copyright (c) 2016 Intel Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <zephyr.h>
|
||||
|
||||
#include <ipm.h>
|
||||
#include <ipm/ipm_quark_se.h>
|
||||
#include <device.h>
|
||||
#include <init.h>
|
||||
#include <misc/printk.h>
|
||||
#include <string.h>
|
||||
|
||||
QUARK_SE_IPM_DEFINE(ping_ipm, 0, QUARK_SE_IPM_INBOUND);
|
||||
QUARK_SE_IPM_DEFINE(message_ipm0, 1, QUARK_SE_IPM_INBOUND);
|
||||
QUARK_SE_IPM_DEFINE(message_ipm1, 2, QUARK_SE_IPM_INBOUND);
|
||||
QUARK_SE_IPM_DEFINE(message_ipm2, 3, QUARK_SE_IPM_INBOUND);
|
||||
|
||||
/* specify delay between greetings (in ms); compute equivalent in ticks */
|
||||
|
||||
#define SLEEPTIME 1100
|
||||
#define SLEEPTICKS (SLEEPTIME * sys_clock_ticks_per_sec / 800)
|
||||
|
||||
#define STACKSIZE 2000
|
||||
|
||||
char fiberStack[STACKSIZE];
|
||||
uint8_t counters[3];
|
||||
|
||||
struct nano_sem nanoSemTask;
|
||||
struct nano_sem nanoSemFiber;
|
||||
|
||||
void ping_ipm_callback(void *context, uint32_t id, volatile void *data)
|
||||
{
|
||||
printk("counters: %d %d %d\n", counters[0], counters[1], counters[2]);
|
||||
}
|
||||
|
||||
static const char dat1[] = "abcdefghijklmno";
|
||||
static const char dat2[] = "pqrstuvwxyz0123";
|
||||
|
||||
|
||||
void message_ipm_callback(void *context, uint32_t id, volatile void *data)
|
||||
{
|
||||
uint8_t *counter = (uint8_t *)context;
|
||||
char *datac = (char *)data;
|
||||
const char *expected;
|
||||
|
||||
if (*counter != id) {
|
||||
printk("expected %d got %d\n", *counter, id);
|
||||
}
|
||||
|
||||
if (id & 0x1) {
|
||||
expected = dat2;
|
||||
} else {
|
||||
expected = dat1;
|
||||
}
|
||||
|
||||
if (strcmp(expected, datac)) {
|
||||
printk("unexpected data payload\n");
|
||||
}
|
||||
(*counter)++;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
struct device *ipm;
|
||||
|
||||
ipm = device_get_binding("ping_ipm");
|
||||
ipm_register_callback(ipm, ping_ipm_callback, NULL);
|
||||
ipm_set_enabled(ipm, 1);
|
||||
|
||||
ipm = device_get_binding("message_ipm0");
|
||||
ipm_register_callback(ipm, message_ipm_callback, &counters[0]);
|
||||
ipm_set_enabled(ipm, 1);
|
||||
|
||||
ipm = device_get_binding("message_ipm1");
|
||||
ipm_register_callback(ipm, message_ipm_callback, &counters[1]);
|
||||
ipm_set_enabled(ipm, 1);
|
||||
|
||||
ipm = device_get_binding("message_ipm2");
|
||||
ipm_register_callback(ipm, message_ipm_callback, &counters[2]);
|
||||
ipm_set_enabled(ipm, 1);
|
||||
|
||||
|
||||
while (1) {
|
||||
/* say "hello" */
|
||||
printk("Hello from ARC!\n");
|
||||
|
||||
task_sleep(SLEEPTICKS);
|
||||
}
|
||||
}
|
6
samples/ipm/ipm_demo_lmt/Makefile
Normal file
6
samples/ipm/ipm_demo_lmt/Makefile
Normal file
|
@ -0,0 +1,6 @@
|
|||
BOARD ?= arduino_101
|
||||
MDEF_FILE = prj.mdef
|
||||
KERNEL_TYPE = micro
|
||||
CONF_FILE = prj.conf
|
||||
|
||||
include ${ZEPHYR_BASE}/Makefile.inc
|
9
samples/ipm/ipm_demo_lmt/prj.conf
Normal file
9
samples/ipm/ipm_demo_lmt/prj.conf
Normal file
|
@ -0,0 +1,9 @@
|
|||
CONFIG_PRINTK=y
|
||||
CONFIG_KERNEL_BIN_NAME="lakemont"
|
||||
CONFIG_ARC_INIT=y
|
||||
CONFIG_IPM=y
|
||||
CONFIG_IPM_QUARK_SE=y
|
||||
CONFIG_IPM_QUARK_SE_MASTER=y
|
||||
CONFIG_IPM_CONSOLE_RECEIVER=y
|
||||
CONFIG_NANO_TIMEOUTS=y
|
||||
CONFIG_TIMESLICE_SIZE=1
|
13
samples/ipm/ipm_demo_lmt/prj.mdef
Normal file
13
samples/ipm/ipm_demo_lmt/prj.mdef
Normal file
|
@ -0,0 +1,13 @@
|
|||
% Application : Hello demo
|
||||
|
||||
% TASK NAME PRIO ENTRY STACK GROUPS
|
||||
% ====================================================
|
||||
TASK TASKA 7 main_task 2048 [EXE]
|
||||
TASK MSG_TASK0 7 message_source_task_0 2048 [EXE]
|
||||
TASK MSG_TASK1 7 message_source_task_1 2048 [EXE]
|
||||
TASK MSG_TASK2 7 message_source_task_2 2048 [EXE]
|
||||
|
||||
% SEMA NAME
|
||||
% =============
|
||||
SEMA TASKASEM
|
||||
SEMA TASKBSEM
|
5
samples/ipm/ipm_demo_lmt/src/Makefile
Normal file
5
samples/ipm/ipm_demo_lmt/src/Makefile
Normal file
|
@ -0,0 +1,5 @@
|
|||
ccflags-y += ${PROJECTINCLUDE}
|
||||
ccflags-y +=-I$(srctree)/include/drivers
|
||||
ccflags-y +=-I$(srctree)/drivers -I$(srctree)/arch/x86
|
||||
|
||||
obj-y = hello.o
|
143
samples/ipm/ipm_demo_lmt/src/hello.c
Normal file
143
samples/ipm/ipm_demo_lmt/src/hello.c
Normal file
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2014 Wind River Systems, Inc.
|
||||
* Copyright (c) 2016 Intel Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <misc/printk.h>
|
||||
#include <zephyr.h>
|
||||
#include <ipm.h>
|
||||
#include <ipm/ipm_quark_se.h>
|
||||
|
||||
QUARK_SE_IPM_DEFINE(ping_ipm, 0, QUARK_SE_IPM_OUTBOUND);
|
||||
QUARK_SE_IPM_DEFINE(message_ipm0, 1, QUARK_SE_IPM_OUTBOUND);
|
||||
QUARK_SE_IPM_DEFINE(message_ipm1, 2, QUARK_SE_IPM_OUTBOUND);
|
||||
QUARK_SE_IPM_DEFINE(message_ipm2, 3, QUARK_SE_IPM_OUTBOUND);
|
||||
|
||||
/* specify delay between greetings (in ms); compute equivalent in ticks */
|
||||
|
||||
#define SLEEPTIME 1000
|
||||
#define SLEEPTICKS (SLEEPTIME * sys_clock_ticks_per_sec / 1000)
|
||||
#define SCSS_REGISTER_BASE 0xB0800000
|
||||
#define SCSS_SS_STS 0x0604
|
||||
|
||||
#define PING_TICKS 100
|
||||
#define STACKSIZE 2000
|
||||
|
||||
#define MSG_FIBER_PRI 6
|
||||
#define MAIN_FIBER_PRI 2
|
||||
#define PING_FIBER_PRI 4
|
||||
|
||||
char fiber_stacks[2][STACKSIZE];
|
||||
|
||||
uint32_t scss_reg(uint32_t offset)
|
||||
{
|
||||
volatile uint32_t *ret = (volatile uint32_t *)(SCSS_REGISTER_BASE +
|
||||
offset);
|
||||
return *ret;
|
||||
}
|
||||
|
||||
static const char dat1[] = "abcdefghijklmno";
|
||||
static const char dat2[] = "pqrstuvwxyz0123";
|
||||
|
||||
|
||||
void message_source(struct device *ipm)
|
||||
{
|
||||
uint8_t counter = 0;
|
||||
|
||||
printk("sending messages for IPM device %x\n", ipm);
|
||||
|
||||
while (1) {
|
||||
ipm_send(ipm, 1, counter++, dat1, 16);
|
||||
ipm_send(ipm, 1, counter++, dat2, 16);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void message_source_task_0(void)
|
||||
{
|
||||
message_source(device_get_binding("message_ipm0"));
|
||||
}
|
||||
|
||||
void message_source_task_1(void)
|
||||
{
|
||||
message_source(device_get_binding("message_ipm1"));
|
||||
}
|
||||
|
||||
void message_source_task_2(void)
|
||||
{
|
||||
message_source(device_get_binding("message_ipm2"));
|
||||
}
|
||||
|
||||
void ping_source_fiber(int arg1, int arg2)
|
||||
{
|
||||
ARG_UNUSED(arg1);
|
||||
ARG_UNUSED(arg2);
|
||||
|
||||
struct device *ipm = device_get_binding("ping_ipm");
|
||||
|
||||
while (1) {
|
||||
fiber_sleep(PING_TICKS);
|
||||
printk("pinging arc for counter status\n");
|
||||
ipm_send(ipm, 1, 0, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void main_fiber(int arg1, int arg2)
|
||||
{
|
||||
ARG_UNUSED(arg1);
|
||||
ARG_UNUSED(arg2);
|
||||
int ctr = 0;
|
||||
uint32_t ss_sts;
|
||||
|
||||
while (1) {
|
||||
/* say "hello" */
|
||||
printk("Hello from lakemont! (%d) ", ctr++);
|
||||
|
||||
ss_sts = scss_reg(SCSS_SS_STS);
|
||||
switch (ss_sts) {
|
||||
case 0x4000:
|
||||
printk("ARC is halted");
|
||||
break;
|
||||
case 0x0400:
|
||||
printk("ARC is sleeping");
|
||||
break;
|
||||
case 0:
|
||||
printk("ARC is running");
|
||||
break;
|
||||
default:
|
||||
printk("ARC status: %x", ss_sts);
|
||||
break;
|
||||
}
|
||||
|
||||
printk(", mailbox status: %x mask %x\n", scss_reg(0xac0),
|
||||
scss_reg(0x4a0));
|
||||
|
||||
/* wait a while, then let other task have a turn */
|
||||
fiber_sleep(SLEEPTICKS);
|
||||
}
|
||||
}
|
||||
|
||||
void main_task(void)
|
||||
{
|
||||
printk("===== app started ========\n");
|
||||
|
||||
task_fiber_start(&fiber_stacks[0][0], STACKSIZE, main_fiber,
|
||||
0, 0, MAIN_FIBER_PRI, 0);
|
||||
|
||||
task_fiber_start(&fiber_stacks[1][0], STACKSIZE, ping_source_fiber,
|
||||
0, 0, PING_FIBER_PRI, 0);
|
||||
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue