Skip to content

Commit

Permalink
add TEST-Code for Multicore in aps_cxx_audio_detect_main.cxx
Browse files Browse the repository at this point in the history
  • Loading branch information
inscape-sa committed Dec 17, 2019
1 parent 0621b84 commit b27ac54
Show file tree
Hide file tree
Showing 5 changed files with 484 additions and 46 deletions.
Expand Up @@ -28,6 +28,13 @@

#include <arch/chip/cxd56_audio.h>

/* include API for MultiCore Management */
#include "worker_ctrl.h"
#include "aps_cxx_audio_detect.h"

/* Worker ELF path */
#define WORKER_FILE "/mnt/spif/aps_cxx_audio_detect"

/** ---
* This Code is in NameSpace "MemMgrLite"
* (it's same as memory_manager).
Expand Down Expand Up @@ -163,12 +170,11 @@ static void app_recorde_process(uint32_t rec_time);
/*** FILE ACCESS **/
static bool app_open_output_file_wav(void);
static void app_close_output_file_wav(void);
#if 0
static void app_write_output_file_wav(uint32_t size);
#endif
static bool app_update_wav_file_size(void);
static bool app_write_wav_header(void);
static bool app_init_wav_header(void);
/** ASMP **/
static int test_subcore_ctrl(void);

/** --- Static Variables */

Expand All @@ -185,6 +191,8 @@ static WAVHEADER s_wav_header;
/** Start Programs */
extern "C" int aps_cxx_audio_detect_main(int argc, char *argv[])
{
int ret;

printf("Start aps_cxx_audio_detect\n");

/* First, initialize the shared memory and memory utility used by AudioSubSystem. */
Expand Down Expand Up @@ -249,6 +257,14 @@ extern "C" int aps_cxx_audio_detect_main(int argc, char *argv[])
return 1;
}

/** -- TEST CODE START -- */
ret = test_subcore_ctrl();
if (ret < 0) {
printf("Error: test_subcore_ctrl failure.\n");
return 1;
}
/** -- TEST CODE END -- */

/* Start recorder operation. */
if (!app_start_recorder_wav()) {
printf("Error: app_start_recorder() failure.\n");
Expand Down Expand Up @@ -870,3 +886,100 @@ static bool app_stop_recorder_wav(void)
return true;
}

/*********************************
* Task Control API
* from Main-Core to Sub-Core(DSP)
*********************************/
/** Start Programs */
static int test_subcore_ctrl(void)
{
WorkerCtrl *pwc;
uint32_t msgdata;
int data = 0x1234;
int ret;
void *buf;

pwc = new WorkerCtrl(WORKER_FILE);
/* Initialize MP mutex and bind it to MP task */
if (!pwc->getReady()) {
printf("WorkerCtrl() constructor failure.\n");
return -1;
}

ret = pwc->initMutex(APS_CXX_AUDIO_DETECTKEY_MUTEX);
if (ret < 0) {
printf("initMutex(mutex) failure. %d\n", ret);
return ret;
}

ret = pwc->initMq(APS_CXX_AUDIO_DETECTKEY_MQ);
if (ret < 0) {
printf("initMq(shm) failure. %d\n", ret);
return ret;
}

buf = pwc->initShm(APS_CXX_AUDIO_DETECTKEY_SHM, APS_CXX_AUDIO_DETECTKEY_SHM_SIZE);
if (buf == NULL) {
printf("initShm() failure. %d\n", ret);
return ret;
}
printf("attached at %08x\n", (uintptr_t)buf);

ret = pwc->execTask();
if (ret < 0) {
printf("execTask() failure. %d\n", ret);
return ret;
}

for (int loop = 0; loop < 10; loop++) {
/* Send command to worker */
ret = pwc->send((uint8_t)MSG_ID_APS_CXX_AUDIO_DETECT_ACT, (uint32_t) &data);
if (ret < 0) {
printf("send() failure. %d\n", ret);
return ret;
}

/* Wait for worker message */
ret = pwc->receive((uint32_t *)&msgdata);
if (ret < 0) {
printf("recieve() failure. %d\n", ret);
return ret;
}
printf("Worker response: ID = %d, data = %x\n",
ret, *((int *)msgdata));

/* Lock mutex for synchronize with worker after it's started */
pwc->lock();
printf("Worker said: %s\n", buf);
pwc->unlock();
}

/* Send command to worker */
ret = pwc->send((uint8_t)MSG_ID_APS_CXX_AUDIO_DETECT_EXIT, (uint32_t) &data);
if (ret < 0) {
printf("send() failure. %d\n", ret);
return ret;
}

/* Wait for worker message */
ret = pwc->receive((uint32_t *)&msgdata);
if (ret < 0) {
printf("recieve() failure. %d\n", ret);
return ret;
}
printf("Worker response: ID = %d, data = %x\n",
ret, *((int *)msgdata));


/* Destroy worker */
ret = pwc->destroyTask();
if (ret < 0) {
printf("destroyTask() failure. %d\n", ret);
return ret;
}
printf("Worker exit status = %d\n", ret);

/* Finalize all of MP objects */
delete pwc;
return 0;
}
160 changes: 160 additions & 0 deletions _aps_samples/aps00_sandbox/aps_cxx_audio_detect/worker_ctrl.cxx
@@ -0,0 +1,160 @@
#include "worker_ctrl.h"

/** WorkerCtrl (constructor)
* - arg = program on sub-core
* - geneate task, and assign at a CPU.
*/
WorkerCtrl::WorkerCtrl(const char *setFileName)
{
int ret;

this->retcode = -1;
this->status = TASK_EMPTY;
this->filename = setFileName;
ret = mptask_init(&this->mptask, this->filename);
if (ret != 0) {
return;
}
ret = mptask_assign(&this->mptask);
if (ret != 0) {
return;
}
this->status = TASK_READY;
return;
}

/** WorkerCtrl (destructor)
* - delete shm, mutex, mq
*/
WorkerCtrl::~WorkerCtrl(void)
{
/* Finalize all of MP objects */
mpshm_detach(&this->shm);
mpshm_destroy(&this->shm);
mpmutex_destroy(&this->mutex);
mpmq_destroy(&this->mq);
}

/** getReady
* - check already init all task-resources
*/
bool WorkerCtrl::getReady(void)
{
return (this->status == TASK_READY)? true : false;
}

/** initMutex
* - init mutex in TaskResource as ID
*/
int WorkerCtrl::initMutex(int id)
{
int ret;
ret = mpmutex_init(&this->mutex, id);
if (ret < 0) {
return ret;
}
ret = mptask_bindobj(&this->mptask, &this->mutex);
if (ret < 0) {
return ret;
}
return 0;
}

/** initMq
* - init Message-Queue in TaskResource as ID
*/
int WorkerCtrl::initMq(int id)
{
int ret;
ret = mpmq_init(&this->mq, id, mptask_getcpuid(&this->mptask));
if (ret < 0) {
return ret;
}
ret = mptask_bindobj(&this->mptask, &this->mq);
if (ret < 0) {
return ret;
}
return 0;
}

/** initShm
* - init Shared-memory in TaskResource as ID
*/
void *WorkerCtrl::initShm(int id, ssize_t size)
{
int ret;
ret = mpshm_init(&this->shm, id, size);
if (ret < 0) {
return NULL;
}
ret = mptask_bindobj(&this->mptask, &this->shm);
if (ret < 0) {
return NULL;
}
/* Map shared memory to virtual space */
this->buf = mpshm_attach(&this->shm, size);
if (!this->buf) {
return NULL;
}
return buf;
}

/** execTask
* - start Task on sub-core
*/
int WorkerCtrl::execTask(void)
{
return mptask_exec(&this->mptask);
}

/** destroyTask
* - force Exit and Destroy Task on sub-core
*/
int WorkerCtrl::destroyTask(void)
{
mptask_destroy(&this->mptask, false, &this->retcode);
return this->retcode;
}

/** lock
* - Entering Critical-Section with mutex
*/
void WorkerCtrl::lock(void)
{
mpmutex_lock(&this->mutex);
}

/** unlock
* - Exit Critical-Section with mutex
*/
void WorkerCtrl::unlock(void)
{
mpmutex_unlock(&this->mutex);
}

/** send
* - send message with (id,value) via MQ
*/
int WorkerCtrl::send(int8_t msgid, uint32_t value)
{
return mpmq_send(&this->mq, msgid, value);
}

/** receive
* - receive message (id,value) via MQ
* - it can be used for nonblocking receive.
*/
int WorkerCtrl::receive(uint32_t *pvalue, bool nonblocking)
{
int ret;
uint32_t gabage;
if (pvalue == NULL) {
pvalue = &gabage;
}
if (nonblocking) {
ret = mpmq_timedreceive(&this->mq, pvalue, MPMQ_NONBLOCK);
} else {
ret = mpmq_receive(&this->mq, pvalue);
}
return ret;
}
47 changes: 47 additions & 0 deletions _aps_samples/aps00_sandbox/aps_cxx_audio_detect/worker_ctrl.h
@@ -0,0 +1,47 @@
#ifndef __WORKER_CTRL_H__
#define __WORKER_CTRL_H__

#include <sdk/config.h>
#include <stdio.h>
#include <string.h>

#include <asmp/asmp.h>
#include <asmp/mptask.h>
#include <asmp/mpshm.h>
#include <asmp/mpmq.h>
#include <asmp/mpmutex.h>

class WorkerCtrl {
public:
typedef enum e_task_status {
TASK_EMPTY,
TASK_READY,
} TASK_STAT;
private:
const char *filename;
TASK_STAT status;
mptask_t mptask;
mpmq_t mq;
mpmutex_t mutex;
mpshm_t shm;
void *buf;
int retcode;

private:
WorkerCtrl();
public:
WorkerCtrl(const char *filename);
~WorkerCtrl(void);
bool getReady(void);
int initMutex(int id);
int initMq(int id);
void *initShm(int id, ssize_t size);
int execTask(void);
int destroyTask(void);
void lock(void);
void unlock(void);
int send(int8_t msgid, uint32_t value);
int receive(uint32_t *pvalue, bool nonblocking = false);
};

#endif /* __WORKER_CTRL_H__ */

0 comments on commit b27ac54

Please sign in to comment.