转经典文章一篇。。。helloworld dsplink

Davinci之调试DSP

被卖到公司实习马上就快一年期满了。这大半年又正好赶上第二轮本命年,真是酸甜苦辣咸,一言难尽。从现在算是放假了,最后一个暑假。天亮了就回家,听说正好奥运圣火也到天津了。不过人山人海的,没什么凑热闹的兴趣。还是清清静静地给我们家小妮妮过周岁来得好,呵呵,都一年了还没怎么当过这个新舅舅呢!小的时候觉得大人们榆木脑袋得不可思议,明明我们只想要什么什么就可以开心得不行了,可他们就是不明白。现在因果循环转回来,也真的不知道该怎么对待小孩子?扯远了,言归正传,紧接着终于要回实验室发愁毕业论文的事情,公司那边的事情恐怕再不会沾手了。给好久以前的笔记系列补上一段,算是个纪念吧!

据我的孤陋寡闻所知,用Davinci搞开发的,大多数都用走CE+FC那套正统大路。我们因为一直是自己摸着石头,就走上了DSPLink+CMEM这条小道。走小路的人貌似很少,这里也暂时不去讲怎么用DSPLink+CMEM来开发。总之反正不管是用的哪套东西,调试DSP程序始终都是个大难题。首先,以前的CCS+仿真器的模式,在双核下就不好使了。用仿真器就跑不起系统来,没有系统就没法调系统下的程序——鸡不下蛋、蛋不孵鸡;其次,据说系统跑起来以后,再打开CCS可以调DSP的状态。这个要求要打开DSP的锁。我没明白是怎么弄的,而且就算明白了,这法子貌似也只能调下共享内存。结论就是,“仿真器+双核”是个很难搞甚至搞不定的东西。所以我们试着回归linux的程序调试——不是gdb,而是printf。

DSP程序的printf貌似是给CCS看的,log/trace又被JTAG金屋藏娇,想改个驱动去抓贼见脏却不知道从何下手。最后只好从DSPLink的MSGQ下手了。论机制,这个原本是高速串口的设备接口,就是用来点对点传输数据的。再加上DSPLink底层的零拷贝驱动,理论上每秒10000(还是8000)次的交换效率还是挺理想的!MSGQ实现过程是,每次由远端(DSP)生成消息(alloc),传送给本地(arm)输出后释放资源(free)。如果在两端各自构造一个消息队列,在算法的每个循环中同步一次,交换双方的资源和处理结果,可以达到并行工作的效果。这里只需要实现一个dsp_printf,1个消息队列单向传输就够了。不过美中不足的是,MSGQ本身貌似不支持中断上下文。因此若用在PRD或者SWI中,就好象失败的隐式内存申请(栈,stack)被调用到,DSP程序会崩溃,反应到ARM端多半是同步函数报告一个超时错误。(对于普遍的隐式变量定义失败的情况,我只知道换作动态malloc堆资源来解决。在DSP/BIOS的tci里加大stack的值根本不管用。不知道具体原因是什么,如何解决?盼高手赐教!)

msgq_debug库使用说明 

目的:解决Davinci开发平台无法输出DSP调试信息的问题
功能:利用msgq机制,令ARM代理DSP的调试信息,并输出给终端 

限制1:仅适用于TI Davinci开发平台中的DSPLink程序开发
限制2:格式字段类似printf(),但总长度(包括\0)不能超过20字节
限制3:必须指定2个参数。不需要参数时可填充任意的32位值;参数不够用时可以多次调用debug_printf()
限制4:不支持字符串参数 

1.文件列表
.
|-- dsp
|   |-- DspBios
|   |   |-- COMPONENT        配置文件2
|   |   `-- Davinci
|   |       `-- ...            DSP/BIOS配置文件
|   |-- SOURCES                配置文件1
|   |-- msgq_debug.c        msgq_debug头文件
|   |-- msgq_debug.h        msgq_debug函数实现
|   `-- ...                    DSP程序
|
|-- gpp
|   |-- Linux
|   |   |-- COMPONENT        配置文件2
|   |   `-- ...                Linux主程序
|   |-- SOURCES                配置文件1
|   |-- msgq_debug.c        msgq_debug头文件
|   |-- msgq_debug.h        msgq_debug函数实现
|   `-- ...                    DSPLink接口程序
|
`-- ...                        编译脚本、说明文件等

wanyongbiao1 发表于 2009-9-5 15:30

2.API列表
DSP
    Int debug_init();
    Int debug_printf (Uint16 poolid, const char * fmt, Uint32 arg0, Uint32 arg1); 

ARM
    NORMAL_API DSP_STATUS DEBUG_Create (PoolId poolid); 

3.在dsplink工程中使用msgq_debug的方法
dsp/SOURCES
    SOURCES := msgq_debug.c \ 

dsp/DspBios/COMPONENT
    原工程配置文件无需改变 

dsp程序
    // 说明:在第一个debug_printf()前执行一次即可
    // 作用:locate remote massage queue named "DebugMSGQ"
    Int debug_init(); 

    // 说明:在任意位置向ARM传送调试信息
    // 作用:allocate a new message, and put it to remote massage queue
    // 举例:debug_printf(SAMPLE_POOL_ID,"DSP loop (%d)\n", i, 0);
    Int debug_printf (Uint16 poolid, const char * fmt, Uint32 arg0, Uint32 arg1); 

gpp/SOURCES
    SOURCES :=    msgq_debug.c    \ 

gpp/Linux/COMPONENT
    EXP_HEADERS := msgq_debug.h    \ 

linux/DSPLink程序
    // 说明:初始化本地debug消息队列,启动接收线程
    // 作用:open local massage queue named "DebugMSGQ"
             create a pthread getting and printing messages in a loop
    // 举例:DEBUG_Create(SAMPLE_POOL_ID);
    NORMAL_API DSP_STATUS DEBUG_Create (PoolId poolid); 

  

=============== 下面是实现的源码 =============== 

---------------------------------- GPP ---------------------------------- 

/** ============================================================================
*  @file   msgq_debug.c
*  ============================================================================
*  Copyright (c) Muddle Liu 2008
*  ============================================================================
*/ 

/*  ----------------------------------- DSP/BIOS Link                   */
#include <gpptypes.h>
#include <dsplink.h>
#include <errbase.h>
#include <platform.h>
#include <msgqdefs.h> 

/*  ----------------------------------- Profiling                       */
#include <profile.h> 

/*  ----------------------------------- DSP/BIOS LINK API               */
#include <proc.h>
#include <msgq.h>
#include <pool.h> 

/*  ----------------------------------- Application Header              */
#include <msgq_debug.h>
#include <pthread.h>
#include <stdio.h> 

#if defined (__cplusplus)
EXTERN "C" {
#endif /* defined (__cplusplus) */ 

//#ifdef __DEBUG
#define __D(fmt, args...) printf("DSPDEBUG: " fmt, ## args)
//#else
//#define __D(fmt, args...)
//#endif 

typedef struct DebugMsg {
#define    STR_LEN    20
#define    ARG_NUM    2
    MsgqMsgHeader    header;
    Char8            str[STR_LEN];
    Uint32            arg[ARG_NUM];
#undef    STR_LEN
#undef    ARG_NUM
} debugmsg_t; 

/** ============================================================================
*  @const  DSPLINK_BUFFER_SIZE
*
*  @desc   Messaging buffer used by the application.
*          Note: This buffer is aligned according to the alignment expected
*          by the platform.
*  ============================================================================
*/
#define DEBUG_BUFFER_SIZE  DSPLINK_ALIGN (sizeof(debugmsg_t),       \
                                        DSPLINK_BUF_ALIGN) 

/** ============================================================================
*  @const  DebugMSGQ
*
*  @desc   Name of the Debug MSGQ on the GPP.
*  ============================================================================
*/
STATIC Char8 DebugGppMsgqName [DSP_MAX_STRLEN] = "DebugMSGQ" ; 

/** ============================================================================
*  @name   DebugGppMsgq
*
*  @desc   Local GPP's MSGQ Object.
*  ============================================================================
*/
STATIC MsgqQueue DebugGppMsgq = (Uint32) MSGQ_INVALIDMSGQ ; 

void* DEBUG_Execute (void*); 

/** ============================================================================
*  @func   DEBUG_Create
*
*  @desc   This function allocates and initializes resources used by
*          this application.
*  ============================================================================
*/
NORMAL_API
DSP_STATUS
DEBUG_Create (PoolId poolid)
{
    DSP_STATUS status = DSP_SOK;
    pthread_t pid; 

    __D("Entered DEBUG_Create ()\n"); 

    /*
     *  Open the GPP's message queue
     */
    if (DSP_SUCCEEDED (status)) {
        status = MSGQ_Open (DebugGppMsgqName, &DebugGppMsgq, NULL) ;
        if (DSP_FAILED (status)) {
            printf("MSGQ_Open () failed. Status = [0x%x]\n", (int)status);
        }
    } 

    /*
     *  Set the message queue that will receive any async. errors
     */
/*    if (DSP_SUCCEEDED (status)) {
        status = MSGQ_SetErrorHandler (DebugGppMsgq, poolid) ;
        if (DSP_FAILED (status)) {
            printf("MSGQ_SetErrorHandler () failed. Status = [0x%x]\n", (int)status);
        }
    }
*/
    printf("Leaving MESSAGE_Create ()\n"); 

    if (pthread_create(&pid, NULL, DEBUG_Execute, NULL)) {
        printf("pthread_create () failed.\n");
        return(DSP_EBASE);
    } 

    return status;


void DEBUG_Delete (Void); 

/** ============================================================================
*  @func   DEBUG_Execute
*
*  @desc   This function implements the execute phase for this application.
*
*  @modif  None
*  ============================================================================
*/
void* DEBUG_Execute (void* arg)
{
    DSP_STATUS status = DSP_SOK ;
    volatile debugmsg_t *msg ;
    int i; 

    __D("Entered DEBUG_Execute ()\n") ; 

    for (i = 1;    DSP_SUCCEEDED(status) ||
    status == DSP_ETIMEOUT || status == DSP_ENOTCOMPLETE; i++) {
        status = MSGQ_Get(DebugGppMsgq, WAIT_NONE/*WAIT_FOREVER*/, (MsgqMsg *)&msg);
        if (DSP_SUCCEEDED (status)) {
            printf("DSP said: ");
            printf((char *)msg->str, msg->arg[0], msg->arg[1]);
            MSGQ_Free ((MsgqMsg)msg) ;
        }
    }
    __D("Leaving DEBUG_Execute ()\n") ;
    DEBUG_Delete(); 

    return NULL;


/** ============================================================================
*  @func   DEBUG_Delete
*
*  @desc   This function releases resources allocated earlier by call to
*          DEBUG_Delete ().
*          During cleanup, the allocated resources are being freed
*          unconditionally. Actual applications may require stricter check
*          against return values for robustness.
*
*  @modif  None
*  ============================================================================
*/
void DEBUG_Delete ()
{
    DSP_STATUS status    = DSP_SOK ;
    DSP_STATUS tmpStatus = DSP_SOK ; 

    __D("Entered DEBUG_Delete ()\n") ; 

    /*
     * Reset the error handler before deleting the MSGQ that receives
     * the error messages.
     */
    tmpStatus = MSGQ_SetErrorHandler (MSGQ_INVALIDMSGQ, MSGQ_INVALIDMSGQ) ;
    if (DSP_SUCCEEDED (status) && DSP_FAILED (tmpStatus)) {
        status = tmpStatus ;
        __D("MSGQ_SetErrorHandler () failed. Status = [0x%x]\n",
                        (int)status) ;
    } 

    /*
     *  Close the GPP's message queue
     */
    tmpStatus = MSGQ_Close (DebugGppMsgq) ;
    if (DSP_SUCCEEDED (status) && DSP_FAILED (tmpStatus)) {
        status = tmpStatus ;
        __D("MSGQ_Close () failed. Status = [0x%x]\n", (int)status) ;
    } 

    __D("Leaving MESSAGE_Delete ()\n") ;


#if defined (__cplusplus)
}
#endif /* defined (__cplusplus) */ 

  

/** ============================================================================
*  @file msgq_debug.h
*  ============================================================================
*  Copyright (c) Muddle Liu 2008
*  ============================================================================
*/ 

#if !defined (MSGQ_DEBUG_H)
#define MSGQ_DEBUG_H 

USES (gpptypes.h)
USES (errbase.h) 

#if defined (__cplusplus)
EXTERN "C" {
#endif /* defined (__cplusplus) */ 

NORMAL_API
DSP_STATUS
DEBUG_Create (PoolId poolid); 

#if defined (__cplusplus)
}
#endif /* defined (__cplusplus) */ 

#endif 

---------------------------------- DSP ----------------------------------

/** ============================================================================
*  @file   msgq_debug.c
*  ============================================================================
*  Copyright (c) Muddle Liu 2008
*  ============================================================================
*/ 

/*  ----------------------------------- DSP/BIOS Headers            */
#include <std.h>
#include <sys.h>
#include <sem.h>
#include <log.h>
#include <tsk.h>
#include <msgq.h>
#include <pool.h> 

/*  ----------------------------------- DSP/BIOS LINK Headers       */
#include <dsplink.h>
#include <platform.h>
#include <failure.h> 

/*  ----------------------------------- Sample Headers              */
#include <message_config.h>
#include <debug.h> 

#include <msgq_debug.h>
#include <string.h> 

#ifdef __cplusplus
extern "C" {
#endif 

#define DebugGppMsgqName "DebugMSGQ" 

MSGQ_Queue DebugMsgq; 

#define DEBUG_BUFFER_SIZE  (DSPLINK_ALIGN (sizeof (debugmsg_t),     \
                          DSPLINK_BUF_ALIGN)) 

/** ============================================================================
*  @func   debug_init
*
*  @desc   Create phase function for the TSKMESSAGE application. Initializes
*          the TSKMESSAGE_TransferInfo structure with the information that will
*          be used by the other phases of the application.
*
*  @modif  None.
*

wanyongbiao1 发表于 2009-9-5 15:31

============================================================================
*/
Int debug_init ()
{
    Int                       status     = SYS_OK ;
    MSGQ_LocateAttrs          syncLocateAttrs ; 

    /* Synchronous locate. */
    status = SYS_ENOTFOUND ;
    while (status == SYS_ENOTFOUND) {
        syncLocateAttrs.timeout = SYS_FOREVER ;
        status = MSGQ_locate (DebugGppMsgqName,
                              &DebugMsgq,
                              &syncLocateAttrs) ;
        if (status == SYS_ENOTFOUND) {
            TSK_sleep (1000) ;
        }
    } 

    return status ;


/** ============================================================================
*  @func   debug_printf
*
*  @desc   Execute phase function for the TSKMESSAGE application. Application
*          receives a message, verifies the id and sends it back.
*
*  @modif  None.
*  ============================================================================
*/
Int debug_printf (Uint16 poolid, const char * fmt, Uint32 arg0, Uint32 arg1)
{
    Int status = SYS_OK ;
    debugmsg_t *msg;
    status = MSGQ_alloc (poolid, (MSGQ_Msg *)&msg, DEBUG_BUFFER_SIZE);
    if (status != SYS_OK) {
        SET_FAILURE_REASON(status);
        return(status);
    } 

    strcpy(msg->str, fmt);
    msg->arg[0] = arg0;
    msg->arg[1] = arg1;
    status = MSGQ_put (DebugMsgq, (MSGQ_Msg)msg);
    if (status != SYS_OK) {
        MSGQ_free ((MSGQ_Msg)msg) ;
        SET_FAILURE_REASON(status);
    }
    return status ;


/** ============================================================================
*  @func   debug_destory
*
*  @desc   Delete phase function for the TSKMESSAGE application. It deallocates
*          all the resources of allocated during create phase of the
*          application.
*
*  @modif  None.
*  ============================================================================
*/
Int debug_destory ()
{
    Int     status     = SYS_OK ; 

    /* Release the located message queue */
    if (DebugMsgq != MSGQ_INVALIDMSGQ) {
        status = MSGQ_release (DebugMsgq) ;
        if (status != SYS_OK) {
            SET_FAILURE_REASON (status) ;
        }
    } 

    return status ;


#if defined (__cplusplus)
}
#endif /* defined (__cplusplus) */ 

  

/** ============================================================================
*  @file   msgq_debug.h
*  ============================================================================
*  Copyright (c) Muddle Liu 2008
*  ============================================================================
*/ 

#ifndef MSGQ_DEBUG_
#define MSGQ_DEBUG_ 

/*  ----------------------------------- DSP/BIOS Headers            */
#include <msgq.h>
#include <sem.h> 

#ifdef __cplusplus
extern "C" {
#endif 

typedef struct DebugMsg {
#define    STR_LEN    20
#define    ARG_NUM    2
        MSGQ_MsgHeader    header;
        Int8            str[STR_LEN];
        Uint32            arg[ARG_NUM];
#undef    STR_LEN
#undef    ARG_NUM
} debugmsg_t;
Int debug_init (); 

Int debug_printf (Uint16 poolid, const char * fmt, Uint32 arg0, Uint32 arg1); 

Int debug_destory (); 

#ifdef __cplusplus
}
#endif /* extern "C" */ 

#endif 

页:  [1]
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值