让vdsp与uclinux共舞(8):vdsp驱动框架

 

快乐虾

http://blog.csdn.net/lights_joy/

[email protected]

 

本文适用于

ADSP-BF561

Visual DSP++ 5.0(update 6)

Bfin-uclinux-2009r1.6

 

欢迎转载,但请保留作者信息

 

 

 

做好前面的准备工作,我们就可以用vdsp进行驱动的开发了。在开发的时候必须注意,虽然我们完全可以在驱动中使用vdsp库,但是如果希望驱动开发完成后能转入GCC编译,那就不要使用任何vdsp特有的东西!

为了尽快验证驱动可行性,在此采用了已经完全移植到vdsp下的内核的头文件,当然对于原始的头文件也不需要太大的改动。

vdsp下新建一个工程,我们就叫它dummy_io吧,为了最后便于转到gcc下编译,我们把它放在linux-2.6.x/drivers/char目录下。

添加一个c文件,内容如下:

/*

简单驱动测试

*/

#ifdef __VISUALDSPVERSION__

#include <config.h>

#endif

 

#include <linux/mm.h>

#include <linux/miscdevice.h>

#include <linux/slab.h>

#include <linux/vmalloc.h>

#include <linux/mman.h>

#include <linux/random.h>

#include <linux/init.h>

#include <linux/raw.h>

#include <linux/tty.h>

#include <linux/capability.h>

#include <linux/ptrace.h>

#include <linux/device.h>

#include <linux/highmem.h>

#include <linux/crash_dump.h>

#include <linux/backing-dev.h>

#include <linux/bootmem.h>

#include <linux/splice.h>

#include <linux/smp_lock.h>

 

#include <asm/uaccess.h>

#include <asm/io.h>

 

static void driver_load();

static void driver_exit();

 

typedef struct _vdsp_comm

{

     int driver_loaded;

     void (*driver_load)();

     int driver_exited;

     void (*driver_exit)();

}vdsp_comm;

 

#pragma section(".vdsp_comm")

static vdsp_comm comm_param =

{

     .driver_loaded = 1,

     .driver_load = driver_load,

     .driver_exited = 0,

     .driver_exit = driver_exit

};

 

static void driver_load()

{

}

 

static void driver_exit()

{

}

 

再添加一个ldf文件,内容如下:

 

ARCHITECTURE(ADSP-BF561)

 

SEARCH_DIR($ADI_DSP/Blackfin/lib)

 

 

// Workarounds are enabled, exceptions are disabled.

#define RT_LIB_NAME(x) lib ## x ## y.dlb

#define RT_LIB_NAME_EH(x) lib ## x ## y.dlb

#define RT_LIB_NAME_MT(x) lib ## x ## mty.dlb

#define RT_LIB_NAME_EH_MT(x) lib ## x ## mty.dlb

#define RT_OBJ_NAME(x) x ## y.doj

#define RT_OBJ_NAME_MT(x) x ## mty.doj

 

 

#define LIBS /

   RT_LIB_NAME(mc561) /

   ,RT_LIB_NAME(small561) /

   ,RT_LIB_NAME_MT(io561) /

   ,RT_LIB_NAME_MT(c561) /

   ,RT_LIB_NAME_MT(event561) /

   ,RT_LIB_NAME_MT(x561) /

   ,RT_LIB_NAME_EH_MT(cpp561) /

   ,RT_LIB_NAME_EH_MT(cpprt561) /

   ,RT_LIB_NAME(f64ieee561) /

   ,RT_LIB_NAME(dsp561) /

   ,RT_LIB_NAME(sftflt561) /

   ,RT_LIB_NAME(etsi561) /

   ,RT_LIB_NAME(ssl561) /

   ,RT_LIB_NAME(drv561) /

   ,RT_LIB_NAME(usb561) /

   ,RT_LIB_NAME(rt_fileio561) /

 

$LIBS = LIBS;

$LIBRARIES_CORE_A =

   RT_LIB_NAME_MT(io561)

   , RT_LIB_NAME(profile561)

   , RT_OBJ_NAME(crtn561)

   , dummy_io.doj

   ;

 

 

#define VDSP_COMM_BEGIN           0x0019a000  

#define VDSP_COMM_END                     0x0019a03f  

#define VDSP_DRIVER_CODE_BEGIN      0x001a0000

#define VDSP_DRIVER_CODE_END  0x001affff

#define VDSP_DRIVER_DATA_BEGIN       0x001b0000

#define VDSP_DRIVER_DATA_END   0x001bffff

 

PROCESSOR p0

{

  

   MEMORY

   {

      MEM_VDSP_COMM        { TYPE(RAM) START(VDSP_COMM_BEGIN) END(VDSP_COMM_END) WIDTH(8) }

      MEM_DRIVER_CODE   { TYPE(RAM) START(VDSP_DRIVER_CODE_BEGIN) END(VDSP_DRIVER_CODE_END) WIDTH(8) }

      MEM_DRIVER_DATA   { TYPE(RAM) START(VDSP_DRIVER_DATA_BEGIN) END(VDSP_DRIVER_DATA_END) WIDTH(8) }

   } /* MEMORY */

  

   OUTPUT($COMMAND_LINE_OUTPUT_DIRECTORY/p0.dxe)

  

   SECTIONS

   {

      .vdsp_comm

      {

         INPUT_SECTION_ALIGN(4)

         INPUT_SECTIONS($LIBRARIES_CORE_A(.vdsp_comm))

      } > MEM_VDSP_COMM

 

      .code

      {

         INPUT_SECTION_ALIGN(4)

         INPUT_SECTIONS($LIBRARIES_CORE_A(program))

      } > MEM_DRIVER_CODE

 

      .data

      {

         INPUT_SECTION_ALIGN(4)

         INPUT_SECTIONS($LIBRARIES_CORE_A(data1))

      } > MEM_DRIVER_CODE

     

   } /* SECTIONS */

} /* p0 */

假如我们改便了内核的编译选项,需要根据map重新定义下面这几个地址的值。

#define VDSP_COMM_BEGIN           0x0019a000  

#define VDSP_COMM_END                     0x0019a03f  

#define VDSP_DRIVER_CODE_BEGIN      0x001a0000

#define VDSP_DRIVER_CODE_END  0x001affff

#define VDSP_DRIVER_DATA_BEGIN       0x001b0000

#define VDSP_DRIVER_DATA_END   0x001bffff

接着我们按f7编译链接,链接完成后自动提示是否下载,同意它下载,观察PC指针,在下载完成后并不会改变程序的状态。

driver_load函数上设置一个断点,让a核继续运行,此时内核将自动检测到数据改变,输出以下信息:

driver loaded detect!prepare to init driver

而后vdsp将在我们的断点处中断下来:

 

这说明,我们的这一步已经成功,我们现在可以实现在vdsp下修改程序并让vdsp自动加载我们的驱动,哈哈!这一切只要按一下F7OK了,是不是比kgdb简单多了?

下面我们将查找内核的函数并调用它。

 

 

 

 

1       参考资料

vdspuclinux共舞(7):在内核为驱动预留空间(2009-11-2)

vdspuclinux共舞(6):用vdsp开发驱动的设想(2009-11-2)

vdspuclinux共舞(5):加入dwarf调试信息(2009-11-2)

vdspuclinux共舞(4):加载uclinux(2009-11-2)

vdspuclinux共舞(3):boot kernel(2009-10-31)

vdspuclinux共舞(2):vdsp的影响(2009-10-31)

VDSPuclinux共舞(1):开篇(2009-10-30)

关于uClinux-2.6(bf561) for VDSP的移植2008/3/11

 

 

 

 

 

你可能感兴趣的:(IO,command,gcc,search,input,output)