Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initializing thread state when starting a new thread using generic thread function. #158

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
03e2b81
Modifications to build environment files to achieve successful build …
ab1aw Feb 7, 2019
25d9f28
Trying to resolve the memory fault - see https://github.com/f9micro/f…
ab1aw Feb 18, 2019
542f618
Revert the modifications for the failed attempt to build and run usin…
ab1aw Feb 18, 2019
2caf08a
Add repeating printf() to ping-pong test to show activity.
ab1aw Feb 18, 2019
ccdb8d9
User app to blink LEDs on the STM32F407 Discovery board. Code taken f…
ab1aw Feb 19, 2019
739cfe1
Modified ping-pong usr app to send incrementing message counter from …
ab1aw Feb 21, 2019
bf8951b
Disable gpioer usr app. Enable ping pong usr app.
ab1aw Feb 21, 2019
5a163fe
Add debug statements to understand logic flow and debug LED functiona…
ab1aw Feb 21, 2019
3b911e5
L4 User Manual
ab1aw Feb 21, 2019
1fbd795
L4 Programming Introduction slideware from The University of New Sout…
ab1aw Feb 21, 2019
e42f337
Experimenting with user app examples demonstrating IPC among three (3…
ab1aw Feb 24, 2019
c185431
Move initiation (trigger) of thread IPC sequencing from ping thread t…
ab1aw Feb 24, 2019
714439f
Converting to using thread info structure and moving to generic threa…
ab1aw Feb 24, 2019
8011d5b
Create a user app demonstration of a mechanism to work around the mis…
ab1aw Feb 25, 2019
dfe5fec
Modifications to pingpong user app to successfully flash the GPIO LEDs.
ab1aw Feb 25, 2019
aec66b1
More interesting sequencing of the GPIO LEDs.
ab1aw Feb 25, 2019
5cd9cd1
Modified the usr/app/gpioer/main.c to properly compile and execute wi…
ab1aw Feb 26, 2019
205d913
More interesting LED blinking sequence for usr/app/gpioer.
ab1aw Feb 26, 2019
4023e62
Attempting to understand why the following line does not execute prop…
ab1aw Feb 26, 2019
68f4b99
Resolved problem w/ user button detection. Problem was due to button …
ab1aw Feb 26, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Documentation/L4-programming-intro.pdf
Binary file not shown.
Binary file added Documentation/l4uman-n1.pdf
Binary file not shown.
3 changes: 2 additions & 1 deletion mk/rules/symmap.mk
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ cmd_elf_to_symmap = $(NM) $< | sort | cut -d' ' -f1,3 | \
{ \
SYM = SYM "{ (void*) (0x"$$1"), "STRCOUNT" },\n"; \
STRCOUNT += length($$2) + 1;\
STRNAME = STRNAME "\"" $$2 "\\0" "\"" "\n"; \
MPOLIA = substr($$2, 1, length($$2)-1); \
STRNAME = STRNAME "\"" MPOLIA "\\0" "\"" "\n"; \
COUNT++; \
} \
END { \
Expand Down
6 changes: 6 additions & 0 deletions user/apps/3ping/build.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Copyright (c) 2013 The F9 Microkernel Project. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

user-apps-3ping-y = \
main.o
219 changes: 219 additions & 0 deletions user/apps/3ping/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
/* Copyright (c) 2013 The F9 Microkernel Project. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#include <platform/link.h>
#include <user_runtime.h>
#include <gpioer.h>
#include <l4/ipc.h>
#include <l4/utcb.h>
#include <l4/pager.h>
#include <l4/thread.h>
#include <l4io.h>

#define STACK_SIZE 512

enum { PING_THREAD, PONG_THREAD, PUNG_THREAD };

typedef struct thread_info_s {
L4_ThreadId_t thread_id;
char *name;
} thread_info_t;

static thread_info_t thread_info[3] __USER_DATA;

#define LABEL 0x1


#if 0
#define __L4_NUM_MRS 16
typedef unsigned long L4_Word_t;
/*
* Message objects
*/
typedef union {
L4_Word_t raw[__L4_NUM_MRS];
L4_Word_t msg[__L4_NUM_MRS];
L4_MsgTag_t tag;
} L4_Msg_t;
#endif

__USER_TEXT
void *ping_thread(void *arg)
{
L4_MsgTag_t tag;
L4_Msg_t msg;
L4_Word_t count = 0;

printf("start %s()\n", thread_info[PING_THREAD].name);

while (1) {
tag = L4_Receive_Timeout(thread_info[PUNG_THREAD].thread_id,
L4_TimePeriod(1000 * 1000));
L4_MsgStore(tag, &msg);
count = L4_MsgWord(&msg, 0);

if (!L4_IpcSucceeded(tag)) {
printf("%p: recv ipc fails\n", L4_MyGlobalId());
printf("%p: ErrorCode = 0x%x\n", L4_MyGlobalId(), L4_ErrorCode());
}
/* FIXME: workaround solution to avoid scheduler starvation */
L4_Sleep(L4_TimePeriod(500 * 1000));

printf("\%s(%d)\t", thread_info[PING_THREAD].name, count);
L4_MsgClear(&msg);
L4_Set_MsgLabel(&msg, LABEL);
L4_MsgAppendWord(&msg, ++count);
L4_MsgLoad(&msg);

tag = L4_Send_Timeout(thread_info[PONG_THREAD].thread_id,
L4_TimePeriod(1000 * 1000));

if (!L4_IpcSucceeded(tag)) {
printf("%p: send ipc fails\n", L4_MyGlobalId());
printf("%p: ErrorCode = 0x%x\n", L4_MyGlobalId(), L4_ErrorCode());
}
/* FIXME: workaround solution to avoid scheduler starvation */
L4_Sleep(L4_TimePeriod(500 * 1000));
}
}

__USER_TEXT
void *pong_thread(void *arg)
{
L4_MsgTag_t tag;
L4_Msg_t msg;
L4_Word_t label;
L4_Word_t count;
L4_Word_t u;

printf("start %s()\n", thread_info[PONG_THREAD].name);

while (1) {
tag = L4_Receive_Timeout(thread_info[PING_THREAD].thread_id,
L4_TimePeriod(1000 * 1000));
L4_MsgStore(tag, &msg);
label = L4_Label(tag);
u = L4_UntypedWords(tag);
count = L4_MsgWord(&msg, 0);

if (!L4_IpcSucceeded(tag)) {
printf("%p: recv ipc fails\n", L4_MyGlobalId());
printf("%p: ErrorCode = 0x%x\n", L4_MyGlobalId(), L4_ErrorCode());
}
printf("%s %d : %d : %d\t", thread_info[PONG_THREAD].name, label, u, count);

L4_MsgClear(&msg);
L4_Set_MsgLabel(&msg, LABEL);
L4_MsgAppendWord(&msg, ++count);
L4_MsgLoad(&msg);

tag = L4_Send_Timeout(thread_info[PUNG_THREAD].thread_id,
L4_TimePeriod(1000 * 1000));

if (!L4_IpcSucceeded(tag)) {
printf("%p: send ipc fails\n", L4_MyGlobalId());
printf("%p: ErrorCode = 0x%x\n", L4_MyGlobalId(), L4_ErrorCode());
}
/* FIXME: workaround solution to avoid scheduler starvation */
L4_Sleep(L4_TimePeriod(500 * 1000));
}
}

__USER_TEXT
void *pung_thread(void *arg)
{
L4_MsgTag_t tag;
L4_Msg_t msg;
L4_Word_t label;
L4_Word_t count;
L4_Word_t u;

printf("start %s()\n", thread_info[PUNG_THREAD].name);

while (1) {
tag = L4_Receive_Timeout(thread_info[PONG_THREAD].thread_id,
L4_TimePeriod(1000 * 1000));
L4_MsgStore(tag, &msg);
label = L4_Label(tag);
u = L4_UntypedWords(tag);
count = L4_MsgWord(&msg, 0);

if (!L4_IpcSucceeded(tag)) {
printf("%p: recv ipc fails\n", L4_MyGlobalId());
printf("%p: ErrorCode = 0x%x\n", L4_MyGlobalId(), L4_ErrorCode());
}
printf("%s %d : %d : %d\n", thread_info[PUNG_THREAD].name, label, u, count);

L4_MsgClear(&msg);
L4_Set_MsgLabel(&msg, LABEL);
L4_MsgAppendWord(&msg, ++count);
L4_MsgLoad(&msg);

tag = L4_Send_Timeout(thread_info[PING_THREAD].thread_id,
L4_TimePeriod(1000 * 1000));

if (!L4_IpcSucceeded(tag)) {
printf("%p: send ipc fails\n", L4_MyGlobalId());
printf("%p: ErrorCode = 0x%x\n", L4_MyGlobalId(), L4_ErrorCode());
}
/* FIXME: workaround solution to avoid scheduler starvation */
L4_Sleep(L4_TimePeriod(500 * 1000));
}
}

__USER_TEXT
static void *main(void *user)
{
// = { {PING_THREAD, "PING", 0}, {PONG_THREAD, "PONG", 0}, {PUNG_THREAD, "PUNG", 0} }

thread_info[PUNG_THREAD].thread_id = pager_create_thread();
thread_info[PONG_THREAD].thread_id = pager_create_thread();
thread_info[PING_THREAD].thread_id = pager_create_thread();

thread_info[PING_THREAD].name = "PING_THREAD";
thread_info[PONG_THREAD].name = "PONG_THREAD";
thread_info[PUNG_THREAD].name = "PUNG_THREAD";

pager_start_thread(thread_info[PUNG_THREAD].thread_id, pung_thread, NULL);
pager_start_thread(thread_info[PONG_THREAD].thread_id, pong_thread, NULL);
pager_start_thread(thread_info[PING_THREAD].thread_id, ping_thread, NULL);

// Prime the pump:
{
L4_MsgTag_t tag;
L4_Msg_t msg;
L4_Word_t count = 0;

printf("\nPrime the pump %d\n", count);

L4_MsgClear(&msg);
L4_Set_MsgLabel(&msg, LABEL);
L4_MsgAppendWord(&msg, count);
L4_MsgLoad(&msg);

tag = L4_Send_Timeout(thread_info[PONG_THREAD].thread_id,
L4_TimePeriod(1000 * 1000));

if (!L4_IpcSucceeded(tag)) {
printf("%p: send ipc fails\n", L4_MyGlobalId());
printf("%p: ErrorCode = 0x%x\n", L4_MyGlobalId(), L4_ErrorCode());
}
else {
printf("\nPump is primed %d\n", count);
}
}

printf("\nEXITING main()\n");
return 0;
}

// DECLARE_FPAGE(0x0, (number_of_threads * 2 * UTCB_SIZE) + (number_of_threads * 2 * STACK_SIZE))
DECLARE_USER(
0,
3ping,
main,
DECLARE_FPAGE(0x0, 6 * UTCB_SIZE + 6 * STACK_SIZE)
DECLARE_FPAGE(0x0, 512)
);
6 changes: 6 additions & 0 deletions user/apps/altpingpong/build.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Copyright (c) 2013 The F9 Microkernel Project. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

user-apps-altpingpong-y = \
main.o
146 changes: 146 additions & 0 deletions user/apps/altpingpong/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/* Copyright (c) 2013 The F9 Microkernel Project. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#include <platform/link.h>
#include <user_runtime.h>
#include <gpioer.h>
#include <l4io.h>
#include <l4/ipc.h>
#include <l4/utcb.h>

#define STACK_SIZE 256

enum { GPIOER_THREAD, BUTTON_MONITOR_THREAD };

static L4_ThreadId_t threads[2] __USER_DATA;

static L4_Word_t last_thread __USER_DATA;
static L4_Word_t free_mem __USER_DATA;

#define LABEL 0x1

__USER_TEXT
void gpioer_thread(void)
{
L4_Msg_t msg;
L4_MsgTag_t tag;

L4_Word_t count = 0;

printf("ping_thread(): built-in leds blinking\n");
//led_init();

while (1) {
printf("ping_thread(%d)\t", count);
L4_MsgClear(&msg);
L4_Set_MsgLabel(&msg, LABEL);
L4_MsgAppendWord(&msg, count++);
L4_MsgLoad(&msg);

tag = L4_Send_Timeout(threads[BUTTON_MONITOR_THREAD],
L4_TimePeriod(1000 * 1000));

if (!L4_IpcSucceeded(tag)) {
printf("%p: send ipc fails\n", L4_MyGlobalId());
printf("%p: ErrorCode = 0x%x\n", L4_MyGlobalId(), L4_ErrorCode());
}
}
}


/* STM32F407-Discovery
* User Button connected on PA0
* as result, for this demo app,
* Because USART4 (PA0, PA1) is conflict,
* choose USART1 (PA9,PA10) or USART2 (PA2,PA3) instead.
**/

#define BUTTON_USER_PIN 0

/* if you use external button, please
* update the BUTTON_CUSTOM_PIN with your own number
**/

#define BUTTON_CUSTOM_PIN BUTTON_USER_PIN

__USER_TEXT
void button_monitor_thread(void)
{
L4_MsgTag_t tag;
L4_Msg_t msg;
L4_Word_t label;
L4_Word_t count;
L4_Word_t u;

while (1) {
tag = L4_Receive_Timeout(threads[GPIOER_THREAD],
L4_TimePeriod(1000 * 1000));
L4_MsgStore(tag, &msg);
label = L4_Label(tag);
u = L4_UntypedWords(tag);
count = L4_MsgWord(&msg, 0);

if (!L4_IpcSucceeded(tag)) {
printf("%p: recv ipc fails\n", L4_MyGlobalId());
printf("%p: ErrorCode = 0x%x\n", L4_MyGlobalId(), L4_ErrorCode());
}
/* FIXME: workaround solution to avoid scheduler starvation */
L4_Sleep(L4_TimePeriod(500 * 1000));
printf("pong_thread %d : %d : %d\n", label, u, count);
}
}

static void __USER_TEXT start_thread(L4_ThreadId_t t, L4_Word_t ip,
L4_Word_t sp, L4_Word_t stack_size)
{
L4_Msg_t msg;

L4_MsgClear(&msg);
L4_MsgAppendWord(&msg, ip);
L4_MsgAppendWord(&msg, sp);
L4_MsgAppendWord(&msg, stack_size);
L4_MsgLoad(&msg);

L4_Send(t);
}

static L4_ThreadId_t __USER_TEXT create_thread(user_struct *user, void (*func)(void))
{
L4_ThreadId_t myself = L4_MyGlobalId();
L4_ThreadId_t child;

child.raw = myself.raw + (++last_thread << 14);

L4_ThreadControl(child, myself, L4_nilthread, myself, (void *) free_mem);
free_mem += UTCB_SIZE + STACK_SIZE;

start_thread(child, (L4_Word_t)func, free_mem, STACK_SIZE);

return child;
}

__USER_TEXT
static void *main(void *p)
{
user_struct *user = (user_struct *)p;
free_mem = user->fpages[0].base;

threads[GPIOER_THREAD] = create_thread(user, gpioer_thread);
threads[BUTTON_MONITOR_THREAD] = create_thread(user, button_monitor_thread);

return 0;
}

#define DEV_SIZE 0x3c00
#define AHB1_1DEV 0x40020000

DECLARE_USER(
0,
altpingpong,
main,
DECLARE_FPAGE(0x0, 2 * UTCB_SIZE + 2 * STACK_SIZE)
/* map thread with AHB DEVICE for gpio accessing */
DECLARE_FPAGE(AHB1_1DEV, DEV_SIZE)
);
Loading