文章目录
  1. 1. CSR8670介绍
  2. 2. ROM的组成
  3. 3. VM Application示例

CSR8670介绍

CSR8670™ 是一款音频片上系统 (SoC) 解决方案,配有无线连接功能、嵌入式闪存和集成式触控传感器,使功能丰富的家庭娱乐系统和可穿戴音频产品能够带来无与伦比的用户体验和卓越的音频性能。

CSR8670有一个XAP processor 和一个Kalimba DSP

Kalimba DSP一般被用来处理音频数据,能被Developer写代码操作寄存器。

在BlueCore3-Mulitmedia的基带控制器(MCU)中运行蓝牙协议栈以及Handfree Profile和>Handset Profile,并从蓝牙的同步面向连接(SCO)链路中提取语音信息并转送给Kalimba >DSP,Kalimba DSP中的软件完成语音处理,再经过数模转换到扬声器放出来,反方向是模>数转换从麦克风中收集语音信息,到Kalimba DSP中进行处理,然后传送给基带控制器,再>通过蓝牙的SCO链路发送出去。

ADK:Audio Development Kit

CSR “Firmware” :蓝牙协议栈代码和一些硬件的控制代码,直接用来操作硬件。这些代码跑在XAP processor上面。

DSP Application:跑在Kalimba DSP上的代码。

VM Application:也是跑在XAP Processor上的代码,但是跑在CSR Firmware的一个Sandbox area,对硬件的访问能力有限。有个特点就是只有在Firmware不忙的时候才运行,实时性较差。

processor architecture

ROM的组成

rom
ROM包括Filessystem 和 CSR Firmware两大块。Filessystem 由VM Application、DSP Application和其它一些数据文件组成。
蓝牙协议栈和硬件控制代码构成Firmware。

VM Application示例

architecture of the application

VM Application由c语言实现,调用现成的蓝牙的库函数,由于提供了库函数源码,理论上也是可以去修改的。通过tasks 和messages去调度程序执行。

Tasks是用于构建应用程序基本组成单元,为提供firmware提供了一个回调接口。
Messages是Tasks 之间用来传递消息的。由Task t, MessageId id, Message payload组成。

  • Task t: 用来标示消息的目标
  • MessageId id:区分不同消息
  • Message payload:额外信息
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    #include <pio.h>
    #include <stdio.h>
    #include <message.h>

    #define BUTTON_A (1 << 0) /* PIO0 is BUTTON_A */
    #define BUTTON_B (1 << 1) /* PIO1 is BUTTON_B */
    #define BUTTON_C (1 << 2) /* PIO2 is BUTTON_C */
    #define BUTTON_D (1 << 3) /* PIO3 is BUTTON_D */

    typedef struct
    {
    TaskData task; /* task is required for messages to be delivered */
    } appState;

    appState app;

    static void app_handler(Task task, MessageId id, Message message)
    {
    switch (id)
    {
    case MESSAGE_PIO_CHANGED:
    handle_pio(task, (MessagePioChanged*)message);
    break;

    default:
    printf("Unhandled message 0x%x\n", id);
    }
    }

    static void handle_pio(Task task, MessagePioChanged *pio)
    {
    if (pio->state & BUTTON_A) printf("Button A pressed\n");
    if (pio->state & BUTTON_B) printf("Button B pressed\n");
    }

    int main(void)
    {
    /* Set app_handler() function to handle app's messages */
    app.task.handler = app_handler;

    /* Set app task to receive PIO messages */
    MessagePioTask(&app.task);

    /* Setup PIO interrupt messages */
    PioDebounce32(BUTTON_A | BUTTON_B, /* PIO pins we are interested in */
    2, 20); /* 2 reads and 20ms between them */

    MessageLoop();

    return 0;
    }

    /* End-of-File */