QuRT: Hello world app for QuRT

DSPAL for QuRT is still missing the pthreads exports and there is no
exported sleep function. These functions are stubbed out for the time being.

This is based on the 6.4.05 version of the Hexagon tools.

The Hexagon tools and DSPAL are needed to build the qurt target.

Signed-off-by: Mark Charlebois <charlebm@gmail.com>
This commit is contained in:
Mark Charlebois 2015-04-22 08:48:48 -07:00
parent c77448747e
commit 6a439f7ddc
9 changed files with 139 additions and 123 deletions

View File

@ -149,9 +149,18 @@ testbuild:
posix: posix:
make PX4_TARGET_OS=posix make PX4_TARGET_OS=posix
nuttx:
make PX4_TARGET_OS=nuttx
qurt:
make PX4_TARGET_OS=qurt
posixrun: posixrun:
Tools/posix_run.sh Tools/posix_run.sh
qurtrun:
make PX4_TARGET_OS=qurt sim
# #
# Unittest targets. Builds and runs the host-level # Unittest targets. Builds and runs the host-level
# unit tests. # unit tests.

View File

@ -87,8 +87,8 @@ ARCHDEFINES += -DCONFIG_ARCH_BOARD_$(CONFIG_BOARD) \
-Drestrict= \ -Drestrict= \
-I$(PX4_BASE)/src/lib/eigen \ -I$(PX4_BASE)/src/lib/eigen \
-I$(PX4_BASE)/src/platforms/qurt/include \ -I$(PX4_BASE)/src/platforms/qurt/include \
-I$(PX4_BASE)/../dspalmc/include \ -I$(PX4_BASE)/../dspal/include \
-I$(PX4_BASE)/../dspalmc/sys \ -I$(PX4_BASE)/../dspal/sys \
-Wno-error=shadow -Wno-error=shadow
# optimisation flags # optimisation flags

View File

@ -54,9 +54,15 @@ typedef int px4_task_t;
#include <sched.h> #include <sched.h>
#define SCHED_DEFAULT SCHED_FIFO #define SCHED_DEFAULT SCHED_FIFO
#ifdef __PX4_LINUX
#define SCHED_PRIORITY_MAX sched_get_priority_max(SCHED_FIFO) #define SCHED_PRIORITY_MAX sched_get_priority_max(SCHED_FIFO)
#define SCHED_PRIORITY_MIN sched_get_priority_min(SCHED_FIFO) #define SCHED_PRIORITY_MIN sched_get_priority_min(SCHED_FIFO)
#define SCHED_PRIORITY_DEFAULT sched_get_priority_max(SCHED_FIFO) #define SCHED_PRIORITY_DEFAULT sched_get_priority_max(SCHED_FIFO)
#elif defined(__PX4_QURT)
#define SCHED_PRIORITY_MAX 0
#define SCHED_PRIORITY_MIN 0
#define SCHED_PRIORITY_DEFAULT 0
#endif
typedef int px4_task_t; typedef int px4_task_t;

View File

@ -51,11 +51,84 @@
#include "apps.h" #include "apps.h"
//#include "px4_middleware.h" //#include "px4_middleware.h"
//static command = "list_builtins"; static const char *commands = "hello start\n";
static void run_cmd(const vector<string> &appargs) {
// command is appargs[0]
string command = appargs[0];
printf("Looking for %s\n", command.c_str());
if (apps.find(command) != apps.end()) {
const char *arg[appargs.size()+2];
unsigned int i = 0;
while (i < appargs.size() && appargs[i] != "") {
arg[i] = (char *)appargs[i].c_str();
printf(" arg = '%s'\n", arg[i]);
++i;
}
arg[i] = (char *)0;
apps[command](i,(char **)arg);
}
else
{
cout << "Invalid command" << endl;
list_builtins();
}
}
static void process_commands(const char *cmds)
{
vector<string> appargs(5);
int i=0;
int j=0;
const char *b = cmds;
bool found_first_char = false;
char arg[20];
// Eat leading whitespace
while (b[i] == ' ') { ++i; };
b = &b[i];
for(;;) {
// End of command line
if (b[i] == '\n' || b[i] == '\0') {
strncpy(arg, b, i);
arg[i] = '\0';
appargs[j] = arg;
// If we have a command to run
if (i > 0 || j > 0)
run_cmd(appargs);
j=0;
if (b[i] == '\n') {
// Eat whitespace
while (b[++i] == ' ');
b = &b[i];
i=0;
continue;
}
else {
break;
}
}
// End of arg
else if (b[i] == ' ') {
strncpy(arg, b, i);
arg[i] = '\0';
appargs[j] = arg;
j++;
// Eat whitespace
while (b[++i] == ' ');
b = &b[i];
i=0;
continue;
}
++i;
}
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
printf("hello\n"); process_commands(commands);
list_builtins(); for (;;) {}
//apps["hello"](i,(char **)arg);;
} }

View File

@ -285,6 +285,14 @@ void hrt_call_at(struct hrt_call *entry, hrt_abstime calltime, hrt_callout callo
hrt_call_internal(entry, calltime, 0, callout, arg); hrt_call_internal(entry, calltime, 0, callout, arg);
} }
void hrt_sleep(uint32_t seconds)
{
}
void hrt_usleep(uint32_t useconds)
{
}
#if 0 #if 0
/* /*
* Convert absolute time to a timespec. * Convert absolute time to a timespec.

View File

@ -53,16 +53,18 @@
#include <string> #include <string>
#include <px4_tasks.h> #include <px4_tasks.h>
#include <hexagon_standalone.h>
#define MAX_CMD_LEN 100 #define MAX_CMD_LEN 100
#define PX4_MAX_TASKS 100 #define PX4_MAX_TASKS 100
struct task_entry struct task_entry
{ {
pthread_t pid; int pid;
std::string name; std::string name;
bool isused; bool isused;
task_entry() : isused(false) {} task_entry() : isused(false) {}
void *sp;
}; };
static task_entry taskmap[PX4_MAX_TASKS]; static task_entry taskmap[PX4_MAX_TASKS];
@ -75,7 +77,7 @@ typedef struct
// strings are allocated after the // strings are allocated after the
} pthdata_t; } pthdata_t;
static void *entry_adapter ( void *ptr ) static void entry_adapter ( void *ptr )
{ {
pthdata_t *data; pthdata_t *data;
data = (pthdata_t *) ptr; data = (pthdata_t *) ptr;
@ -85,8 +87,6 @@ static void *entry_adapter ( void *ptr )
printf("Before px4_task_exit\n"); printf("Before px4_task_exit\n");
px4_task_exit(0); px4_task_exit(0);
printf("After px4_task_exit\n"); printf("After px4_task_exit\n");
return NULL;
} }
void void
@ -103,15 +103,12 @@ px4_task_t px4_task_spawn_cmd(const char *name, int scheduler, int priority, int
unsigned int len = 0; unsigned int len = 0;
unsigned long offset; unsigned long offset;
unsigned long structsize; unsigned long structsize;
char * p = (char *)argv; char * p;
pthread_t task;
pthread_attr_t attr;
struct sched_param param;
// Calculate argc // Calculate argc
while (p != (char *)0) { for(;;) {
p = argv[argc]; p = argv[argc];
printf("arg %d %s\n", argc, argv[argc]);
if (p == (char *)0) if (p == (char *)0)
break; break;
++argc; ++argc;
@ -136,105 +133,29 @@ px4_task_t px4_task_spawn_cmd(const char *name, int scheduler, int priority, int
// Must add NULL at end of argv // Must add NULL at end of argv
taskdata->argv[argc] = (char *)0; taskdata->argv[argc] = (char *)0;
#if 0
rv = pthread_attr_init(&attr);
if (rv != 0) {
printf("px4_task_spawn_cmd: failed to init thread attrs\n");
return (rv < 0) ? rv : -rv;
}
rv = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
if (rv != 0) {
printf("px4_task_spawn_cmd: failed to set inherit sched\n");
return (rv < 0) ? rv : -rv;
}
rv = pthread_attr_setschedpolicy(&attr, scheduler);
if (rv != 0) {
printf("px4_task_spawn_cmd: failed to set sched policy\n");
return (rv < 0) ? rv : -rv;
}
param.sched_priority = priority;
rv = pthread_attr_setschedparam(&attr, &param);
if (rv != 0) {
printf("px4_task_spawn_cmd: failed to set sched param\n");
return (rv < 0) ? rv : -rv;
}
#endif
//rv = pthread_create (&task, &attr, &entry_adapter, (void *) taskdata);
rv = pthread_create (&task, NULL, &entry_adapter, (void *) taskdata);
if (rv != 0) {
if (rv == EPERM) {
//printf("WARNING: NOT RUNING AS ROOT, UNABLE TO RUN REALTIME THREADS\n");
rv = pthread_create (&task, NULL, &entry_adapter, (void *) taskdata);
if (rv != 0) {
printf("px4_task_spawn_cmd: failed to create thread %d %d\n", rv, errno);
return (rv < 0) ? rv : -rv;
}
}
else {
return (rv < 0) ? rv : -rv;
}
}
for (i=0; i<PX4_MAX_TASKS; ++i) { for (i=0; i<PX4_MAX_TASKS; ++i) {
if (taskmap[i].isused == false) { if (taskmap[i].isused == false) {
taskmap[i].pid = task; taskmap[i].pid = i+1;
taskmap[i].name = name; taskmap[i].name = name;
taskmap[i].isused = true; taskmap[i].isused = true;
taskmap[i].sp = malloc(stack_size);;
break; break;
} }
} }
if (i>=PX4_MAX_TASKS) { thread_create(entry_adapter, taskmap[i].sp, i+1, (void *) taskdata);
return -ENOSPC;
} return i+1;
return i;
} }
int px4_task_delete(px4_task_t id) int px4_task_delete(px4_task_t id)
{ {
int rv = 0;
pthread_t pid;
printf("Called px4_task_delete\n"); printf("Called px4_task_delete\n");
return -EINVAL;
if (id < PX4_MAX_TASKS && taskmap[id].isused)
pid = taskmap[id].pid;
else
return -EINVAL;
// If current thread then exit, otherwise cancel
if (pthread_self() == pid) {
taskmap[id].isused = false;
pthread_exit(0);
} else {
rv = pthread_cancel(pid);
}
taskmap[id].isused = false;
return rv;
} }
void px4_task_exit(int ret) void px4_task_exit(int ret)
{ {
int i; thread_stop();
pthread_t pid = pthread_self();
// Get pthread ID from the opaque ID
for (i=0; i<PX4_MAX_TASKS; ++i) {
if (taskmap[i].pid == pid) {
taskmap[i].isused = false;
break;
}
}
if (i>=PX4_MAX_TASKS)
printf("px4_task_exit: self task not found!\n");
else
printf("px4_task_exit: %s\n", taskmap[i].name.c_str());
pthread_exit((void *)(unsigned long)ret);
} }
void px4_killall(void) void px4_killall(void)
@ -250,19 +171,8 @@ void px4_killall(void)
int px4_task_kill(px4_task_t id, int sig) int px4_task_kill(px4_task_t id, int sig)
{ {
int rv = 0; printf("Called px4_task_kill\n");
pthread_t pid; return -EINVAL;
//printf("Called px4_task_delete\n");
if (id < PX4_MAX_TASKS && taskmap[id].pid != 0)
pid = taskmap[id].pid;
else
return -EINVAL;
// If current thread then exit, otherwise cancel
rv = pthread_kill(pid, sig);
return rv;
} }
void px4_show_tasks() void px4_show_tasks()
@ -274,7 +184,7 @@ void px4_show_tasks()
for (idx=0; idx < PX4_MAX_TASKS; idx++) for (idx=0; idx < PX4_MAX_TASKS; idx++)
{ {
if (taskmap[idx].isused) { if (taskmap[idx].isused) {
printf(" %-10s %p\n", taskmap[idx].name.c_str(), taskmap[idx].pid); printf(" %-10s %d\n", taskmap[idx].name.c_str(), taskmap[idx].pid);
count++; count++;
} }
} }
@ -282,3 +192,6 @@ void px4_show_tasks()
printf(" No running tasks\n"); printf(" No running tasks\n");
} }
// STUBS

View File

@ -35,7 +35,7 @@
************************************************************************/ ************************************************************************/
// FIXME - need px4_queue // FIXME - need px4_queue
#include <platforms/linux/include/queue.h> #include <platforms/qurt/include/queue.h>
#include <stddef.h> #include <stddef.h>
__EXPORT void sq_rem(sq_entry_t *node, sq_queue_t *queue); __EXPORT void sq_rem(sq_entry_t *node, sq_queue_t *queue);

View File

@ -40,9 +40,15 @@
*/ */
#include "hello_example.h" #include "hello_example.h"
#include <drivers/drv_hrt.h>
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
/*
* Wrap the sleep call.
*/
__EXPORT extern void hrt_sleep(uint32_t seconds);
px4::AppState HelloExample::appState; px4::AppState HelloExample::appState;
int HelloExample::main() int HelloExample::main()
@ -51,7 +57,7 @@ int HelloExample::main()
int i=0; int i=0;
while (!appState.exitRequested() && i<5) { while (!appState.exitRequested() && i<5) {
sleep(2); hrt_sleep(2);
printf(" Doing work...\n"); printf(" Doing work...\n");
++i; ++i;

View File

@ -44,20 +44,21 @@
#include <string.h> #include <string.h>
#include <sched.h> #include <sched.h>
#define SCHED_DEFAULT SCHED_FIFO
#define SCHED_PRIORITY_MAX sched_get_priority_max(SCHED_FIFO)
#define SCHED_PRIORITY_DEFAULT sched_get_priority_max(SCHED_FIFO)
static int daemon_task; /* Handle of deamon task / thread */ static int daemon_task; /* Handle of deamon task / thread */
//using namespace px4; //using namespace px4;
extern "C" __EXPORT int hello_main(int argc, char *argv[]); extern "C" __EXPORT int hello_main(int argc, char *argv[]);
static void usage()
{
printf("usage: hello {start|stop|status}\n");
}
int hello_main(int argc, char *argv[]) int hello_main(int argc, char *argv[])
{ {
printf("argc = %d %s %s\n", argc, argv[0], argv[1]);
if (argc < 2) { if (argc < 2) {
printf("usage: hello {start|stop|status}\n"); usage();
return 1; return 1;
} }
@ -74,7 +75,7 @@ int hello_main(int argc, char *argv[])
SCHED_PRIORITY_MAX - 5, SCHED_PRIORITY_MAX - 5,
2000, 2000,
PX4_MAIN, PX4_MAIN,
(argv) ? (char* const*)&argv[2] : (char* const*)NULL); (char* const*)argv);
return 0; return 0;
} }
@ -95,6 +96,6 @@ int hello_main(int argc, char *argv[])
return 0; return 0;
} }
printf("usage: hello_main {start|stop|status}\n"); usage();
return 1; return 1;
} }