今天是14号 15号更新,说明,刚开始看程序有点复杂 没办法,必须看代码 
建议首先先把ADK3.5.1中的例程tutorials看完,对学习很有帮助

1.csr中的消息机制

1.1 adk3.5.1中的led的例子

  • csr8670中是以消息机制进行任务调度的,根据消息调用相应的回调函数进行处理,如下面这个例子所示:在主函数中,首先设置PIO为输出并且设置为低电平,然后调用了messagesend函数和messageloop函数
  • TaskData :这个结构体是最重要的,可以看出定义了一个函数指针,其参数有三个
</pre><pre class="prettyprint" name="code" style="white-space: nowrap; word-wrap: break-word; box-sizing: border-box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: 'Source Code Pro', monospace; padding: 5px 5px 5px 60px; font-size: 14px; line-height: 1.45; word-break: break-all; color: rgb(51, 51, 51); border: 1px solid rgba(128, 128, 128, 0.0745098); border-radius: 0px; background-color: rgba(128, 128, 128, 0.0470588);"><code class="hljs d has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">typedef</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> TaskData { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> (*handler)(Task, MessageId, Message); } TaskData;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li></li></ul>
  • messagesend:这个函数能够向某个任务发送消息
  • messageloop:开始任务调度,不会返回
  • static void led_controller1( Task t, MessageId id, Message payload )
    {PioSet32( LED1, (PioGet32() ^ LED1) );MessageSendLater( t, 0, 0, DELAY1 );
    }
    static void led_controller2( Task t, MessageId id, Message payload )
    {PioSet32( LED2, (PioGet32() ^ LED2) );MessageSendLater( t, 0, 0, DELAY2 );
    }
    static TaskData led_controller1_task = { led_controller1 };//实例化了一个任务,并初始化了其参数,即回调函数
    static TaskData led_controller2_task = { led_controller2 };int main(void)
    {PioSetDir32(0xFF, 0xFF);         /* Set all PIO to be output */PioSet32(0xFF, 0);               /* Set all PIO off (0) */MessageSend( &led_controller1_task, 0 , 0 );//第一个参数为发送给哪个任务MessageSend( &led_controller2_task, 0 , 0 );MessageLoop();//开始任务调度return 0;
    }

1.2 hsTaskData结构体

csr中是以消息机制来进行任务的处理的,其中最大的任务为theSink,其结构体如下

/* Sink application data */
typedef struct
{/* Main task */TaskData                 task;//最重要的任务,指向最高层的回到函数,即main函数里边的app_handler/* Config variables */ButtonsTaskData          *theButtonsTask;//按键的任务,这些是最高层任务之下的任务,之所以定义在最高层里面,应该是想让最高层具有知道所有事件运行情况的能力LedTaskData              *theLEDTask;//led显示的任务,同上runtime_block1_t         *rundata;//运行时的数据,目前还不了解config_block1_t          *conf1;//解下来的7个block以后会分析config_block2_t          *conf2;config_block3_t          *conf3;config_block4_t          *conf4;config_block5_t          *conf5;config_block6_t          *conf6;config_block7_t          *conf7;ConfigTone_t              gConfigTones;volume_levels_t          *volume_levels;        /* current operating volume levels for a2dp/usb/wired modes */power_table              *user_power_table;     /* pointer to user power table if available in ps */hfp_common_plugin_params_t  hfp_plugin_params;HFP_features_type        HFP_supp_features;feature_config_type      features;bdaddr                       local_bd_addr; /* Local BD Address of the sink device available in ps *//* Runtime variables *//*下面这些运行时的变量都是在动态的生成或者释放的,每一个和button一样都是一个任务*/Task                     codec_task ;Sink                     routed_audio;uint16                   NoOfReconnectionAttempts;profile_data_t           profile_data[MAX_MULTIPOINT_CONNECTIONS];a2dp_data                *a2dp_link_data;
#ifdef ENABLE_AVRCPavrcp_data               *avrcp_link_data;
#endif    tp_bdaddr                *confirmation_addr;inquiry_data_t           inquiry;#ifdef ENABLE_PBAPpbapc_data_t             pbapc_data;
#endif
#ifdef ENABLE_USBusb_info                 *usb;
#endif
#ifdef ENABLE_PEERbdaddr remote_peer_ag_bd_addr;
#endifuser_eq_bank_t        *PEQ;/*! Runtime flags*//*word 1*/unsigned                 PowerOffIsEnabled:1; /*自行百度结构体的用法,这样写应该是为了节省空间*/unsigned                 SinkInitialising:1;unsigned                 VolumeOrientationIsInverted:1; /*whether or not the vol buttons are inverted*/unsigned                 NetworkIsPresent:1;unsigned                 inquiry_scan_enabled:1;unsigned                 page_scan_enabled:1 ;unsigned                 csr_speech_recognition_is_active:1 ;unsigned                 csr_speech_recognition_tuning_active:1 ;         unsigned                 panic_reconnect:1;              unsigned                 last_outgoing_ag:2 ;   /* which AG made the last outgoing call */unsigned                 audio_prompts_enabled:1;unsigned                 confirmation:1;unsigned                 debug_keys_enabled:1;unsigned                 RepeatCallerIDFlag:1;unsigned                 mute_all_outputs:1;/*word 2*/unsigned                 audio_prompt_language:4; unsigned                 num_audio_prompt_languages:4;unsigned                 MultipointEnable:1;unsigned                 powerup_no_connection:1;    /* bit to indicate device has powered and no connections yet */unsigned                 paging_in_progress:1;       /* bit to indicate that device is curretly paging whilst in connectable state */unsigned                 audioAmpPowerPin:1;         /* bit to indicate logic state of audio amplifier power pin */unsigned                 battery_state:3;unsigned                 gVolButtonsInverted:1;    /*! whether or not the volume button operation is currently inverted*/  /*word 3*/unsigned                 FailAudioNegotiation:1;unsigned                 RenegotiateSco:1;       unsigned                 lbipmEnable:1;             /* enable Low Battery Intelligent Power Management feature */unsigned                 buttons_locked:1;          /* Flag to indicate if button locking is enabled */unsigned                 HeldCallIndex:4;           /* which call to route in the case of multiple held calls */ unsigned                 inquiry_tx:8;/*word 4*/unsigned                 MissedCallIndicated:8;unsigned                 gEventQueuedOnConnection:8 ;/*word 5*/unsigned                 mute_states:3;unsigned                 pbap_access:1;             /* Link Policy expedites PBAP access */unsigned                 dfu_access:1;              /* Link Policy expedites DFU data transfer */unsigned                 hfp_profiles:3;unsigned                 ssr_enabled:1;unsigned                 VoiceRecognitionIsActive:2;unsigned                 PartyModeEnabled:1;
#ifdef ENABLE_PEER    unsigned                 remote_peer_audio_conn_status:3; /* Flag to indicate which Audio sources are connected to the remote peer */unsigned                 tws_qual_enable_peer_open:1; /* Flag to indicate App to trigger opening of Peer media channel */
#elseunsigned                 unused4:4;
#endif/* word 6 */unsigned                 gated_audio:8;              /* Bitmask indicating which audio sources are prevented from being routed */unsigned                 linkLossReminderTime:8;/* word 7 */peer_states_t            peer;
#if defined(ENABLE_PEER) &&  defined( ENABLE_PEER_BATTERY_LEVEL)uint16                   peer_battery_level;
#endif
} hsTaskData;

2.sink工程的流程分析

2.1 sink的初始化和工具

  • 如下图所示,描述了之前提到过的csr的开发流程,即pc工具和开发环境配合使用,所以在程序中需要读取这些配置的参数等数据 

2.2 speaker流程分析

  • 第一步:init函数,对sink工程进行单步调试发现,工程首先进入的入口函数是init函数,而不是main函数,下面都是大致的分析,对整个流程有个初步的认识即可
/* Time critical initialisation */
#ifdef HOSTED_TEST_ENVIRONMENT
void _sink_init(void)
#else
void _init(void)
#endif
{/* Set the application task */theSink.task.handler = app_handler;  /*这个就是上面提及的最重要的任务的回调函数,如果其他任务想让这个任务的事件触发,则向它发送消息,第一个参数为这个任务的TASK*//* set flag to indicate that configuration is being read, use to prevent use of variablesprior to completion of initialisation */theSink.SinkInitialising = TRUE;/*将sink的正在初始化标志置位*//* Read in any PIOs required */configManagerPioMap();/*根据配置文件获取PIO的设置和映射关系*//* Time critical USB setup */usbTimeCriticalInit();/*目前没有用到*/
}
  • 第二步:mian函数,看函数注释说sink引用程序从这里开始,突然发现上面的init函数前面包含了一个下划线,这个带下划线的函数我们应该是单步不到的,应该是系统自动上电执行的,超出我们单步调试的范围,应该是系统内部的函数,目前不是很了解。
<pre name="code" class="cpp">/* The Sink Application starts here...*/
#ifdef HOSTED_TEST_ENVIRONMENT
int sink_main(void)
#else
int main(void)
#endif
{DEBUG (("Main [%s]\n",__TIME__));/* Initialise the Upgrade lib */sinkUpgradeInit(&theSink.task);/*这个和更新有关,暂不考虑*//* check and update as necessary the software version pskey, this is used for ensuring maximumcompatibility with the sinkg configuration tool */configManagerSetVersionNo();/*版本相关*//* Initialise memory required early */configManagerInitMemory();/*这个函数里面开辟了runtime_block1_t         这个结构体,初始化为0*//* initialise memory for the led manager */LedManagerMemoryInit();/*开辟了LedTaskData结构体的空间,初始化为0*//* Initialise device state */AuthResetConfirmationFlags();/*不懂?*//*the internal regs must be latched on (smps and LDO)*/PioSetPowerPin ( TRUE ) ;/*不懂?*/switch (BootGetMode() )/*配置工具可以设置系统的启动模式*/{
#ifdef CVC_PRODTESTcase BOOTMODE_CVC_PRODTEST:/*run the cvc prod test code and dont start the applicaiton */cvcProductionTestEnter() ;break ;
#endifcase BOOTMODE_DFU:/*do nothing special for the DFU boot mode,This mode expects to have the appropriate host interfface enabledDon't start the application *//* Initializing only the system components required for flashing the led pattern in the DFU mode*/configManagerInit(FALSE);LEDManagerIndicateEvent(EventUsrEnterDFUMode);break ;case BOOTMODE_DEFAULT:case BOOTMODE_CUSTOM:case BOOTMODE_USB_LOW_POWER:case BOOTMODE_ALT_FSTAB:default:{/* Initialise the Connection lib */sinkConnectionInit();/*初始化连接库,从这里开始,可以把整个连接库从初始化调用到完成分析一下*/#ifdef TEST_HARNESStest_init();#endif}break ;}/* Make sure the mute states are correctly set up */VolumeSetInitialMuteState();/*静音模式初始化*//* Start the message scheduler loop */MessageLoop();/*开始任务调度*//* Never get here...*/return 0;
}
  • 第三步:连接库的具体初始化过程
  • 2.3.1.sinkConnectionInit函数,注意这个函数使用static修饰
<pre name="code" class="cpp">static void sinkConnectionInit(void)
{/* read the lengths key into a temporary malloc to get pdl length *//*给pdl分配空间*/lengths_config_type * lengths_key = PanicUnlessMalloc(sizeof(lengths_config_type));/* The number of paired devices can be restricted using pskey user 40,  a number between 1 and 8 is allowed *//*读取pdl*/ConfigRetrieve(CONFIG_LENGTHS, lengths_key , sizeof(lengths_config_type) );DEBUG (("PDLSize[%d]\n" , lengths_key->pdl_size ));/* Initialise the Connection Library with the options *//*具体的初始化函数,注意(0001)第一个参数为最上层的任务,第三个参数为pdl的个数*/ConnectionInitEx2(&theSink.task , NULL, lengths_key->pdl_size );/* free the malloc'd memory */free(lengths_key);/*这里需要关注一下,这种malloc,free的模式在工程中很常见,都是先分配空间,使用之后再释放,在哪里看的目的好像是说减少栈内存的使用*/
}
  • 2.3.2.看源代码可知ConnectionInitEx2–>ConnectionInitEx3,所以接下来是ConnectionInitEx3这个函数,参数前三个对应
<pre name="code" class="cpp">void ConnectionInitEx3(Task theAppTask, const msg_filter *msgFilter , uint16 TdlNumberOfDevices  , uint16 options)
{/*注意这里面又有了一个theCm,自己可以分析一下,怎样和最重要的任务产生关系*/theCm.msgFilter = (msgFilter == NULL) ? &defaultMsgFilter : msgFilter;/* Initialise the Connection Library Task, all upstream messages sent byBluestack will be handled by this task *//*这也是个任务,初始化其回调函数*/theCm.task.handler = connectionBluestackHandler;/* If a task is already registered to receive BlueStack prims then we panic! */if (MessageBlueStackTask(connectionGetCmTask())){CL_DEBUG(("ERROR - task already registered\n"));}/* Init the resource locks */initLocks();/* Init the sm_init_msg types.*/theCm.smState.sm_init_msg = sm_init_set_none;/* Store the application task *//*在这一步,将最终要的任务,赋值给这个任务的结构体,这样这个任务就可以向最重要任务发消息*/theCm.theAppTask = theAppTask;/*set the number of devices to the requested value if in the range 1 to 8*/theCm.smState.TdlNumberOfDevices = DEFAULT_NO_DEVICES_TO_MANAGE ;if ((TdlNumberOfDevices >= MIN_NO_DEVICES_TO_MANAGE) && (TdlNumberOfDevices <= MAX_NO_DEVICES_TO_MANAGE)){theCm.smState.TdlNumberOfDevices = TdlNumberOfDevices ;}/* Process options *//* Enable SC */if (options & CONNLIB_OPTIONS_SC_ENABLE)theCm.flags |= CONNECTION_FLAG_SC_ENABLE;/* Enable SC only mode. It implies SC must be turned on as well */if (options & CONNLIB_OPTIONS_SCOM_ENABLE)theCm.flags |= (CONNECTION_FLAG_SCOM_ENABLE | CONNECTION_FLAG_SC_ENABLE);/* Start the initialisation process */MessageSend(connectionGetCmTask(), CL_INTERNAL_INIT_REQ, NO_PAYLOAD);/*这里发送消息给&theCm.task,也即上面赋值过的回调函数connectionBluestackHandler,第二个代表连接内部初始化请求此数值为1,第三个参数延时时间*/
}
  • 2.3.3 现在走进connectionBluestackHandler这个函数看怎样处理这个消息
<pre name="code" class="cpp">/****************************************************************************
NAMEconnectionBluestackHandlerDESCRIPTIONThis is the main task handler for all messages sent to the ConnectionLibrary task.RETURNSvoid
*/
void connectionBluestackHandler(Task task, MessageId id, Message message)
{/* Get access to the Connection Library instance state *//*获取这个传递过来的任务*/connectionState *theCm = (connectionState *)task;connectionStates state = theCm->state;PRINT(("connectionBluestackHandler - Id = 0x%x\n",id));/* Handle Bluestack primitives seperately */switch (id){case MESSAGE_BLUESTACK_DM_PRIM:/*8004*/connectionBluestackHandlerDm(theCm, (DM_UPRIM_T *)message);break;#ifndef CL_EXCLUDE_RFCOMMcase MESSAGE_BLUESTACK_RFCOMM_PRIM:/*8006*/connectionBluestackHandlerRfcomm(theCm, (RFCOMM_UPRIM_T *)message);break;
#endif#if !defined(CL_EXCLUDE_L2CAP) || !defined(DISABLE_BLE)case MESSAGE_BLUESTACK_L2CAP_PRIM:/*8005*/connectionBluestackHandlerL2cap(theCm, (L2CA_UPRIM_T *)message);break;
#endif#ifndef CL_EXCLUDE_SDPcase MESSAGE_BLUESTACK_SDP_PRIM:/*8007*/connectionBluestackHandlerSdp(theCm, (SDS_UPRIM_T *)message);break;
#endifcase MESSAGE_BLUESTACK_UDP_PRIM:/*8015*/case MESSAGE_BLUESTACK_TCP_PRIM:/*8014*/handleUnexpected(connectionUnhandledMessage, theCm->state, id);break;#ifndef CL_EXCLUDE_SDP/* CL_SDP_CLOSE_SEARCH_CFM Primitive arrived as a result of an internalcall to close SDP search, can't avoid so ignoreHandled as a special case to allow the compiler to generate bettercode for the previous switch statements. */case CL_SDP_CLOSE_SEARCH_CFM:break;
#endif/* Everything else must be internal connection library primitives */default:/*可知1会进入这里*/{switch (state)/*然会根据任务的状态判断,我们可以回过头去看看这个任务的状态在什么时间被赋值了,发现没有处理过所以为0,会进入connectionUninitialised这个值也为0*/{case connectionReady:connectionBluestackHandlerReady(theCm, id, message);break;case connectionUninitialised:connectionBluestackHandlerUninitialised(theCm, id, message);/*注意传递过去的参数*/break;case connectionInitialising:connectionBluestackHandlerInitialising(theCm, id, message);break;case connectionTestMode:connectionBluestackHandlerTestMode(theCm, id, message);break;}}}
}
  • 2.3.4 connectionBluestackHandlerUninitialised函数
<pre name="code" class="cpp">static void connectionBluestackHandlerUninitialised(connectionState *theCm, MessageId id, Message message)
{/* Depending upon the message id...*//*由前面可以知道此时相等*/if (id == CL_INTERNAL_INIT_REQ){PRINT(("CL_INTERNAL_INIT_REQ\n"));connectionHandleInternalInit(connectionInit);/*执行这个函数,注意参数为0*/}else{/* Prims we are not handling - Not panicing the app in DEBUG Mode. Just Print this INFO and ignore it.*/CL_DEBUG_INFO(("Ignored Unexpected Message - Code 0x%x State 0x%x MsgId 0x%x\n", connectionUnexpectedCmPrim, theCm->state, id))}
}
  • 2.3.5 connectionHandleInternalInit函数
<pre name="code" class="cpp">void connectionHandleInternalInit(connectionInitState state)
{/* If we're ready to run, change state */    if(state == connectionInitComplete){theCm.state = connectionReady;}else if (theCm.state != connectionInitialising)/*这个成立,此时状态为未初始化*/{theCm.state = connectionInitialising;/*改变状态*//* Start a Timer to notify the Client if the initialisation fails *//*等待一段时间发送CL_INTERNAL_INIT_TIMEOUT_IND这个消息此数值为0,还是向connectionBluestackHandler发送的,注意第三个参数,这个是个时间,很重要下面会分析到*/MessageSendLater(&theCm.task, CL_INTERNAL_INIT_TIMEOUT_IND, NO_PAYLOAD, (uint32) INIT_TIMEOUT);}/* Check to see if all objects have been initialised */if(state == connectionInitComplete){/* Initialise auth requirements to unknown */theCm.smState.authentication_requirements = AUTH_REQ_UNKNOWN;/* Some DM stuff can be initialised only after the DM register has happened so do it here */connectionDmInfoInit();/* Let the application we're ready to go */connectionSendInitCfm(theCm.theAppTask, success, theCm.infoState.version);}else{/* Depending upon the previous object initialised, initialise the next one */switch(state){case connectionInit:/*此时会调用这个函数*/connectionDmInit(); /*这个是个初始化,做什么的不了解*/break;case connectionInitDm:
#ifndef CL_EXCLUDE_RFCOMMconnectionRfcInit();
#elseconnectionL2capInit();
#endifbreak;#ifndef CL_EXCLUDE_RFCOMMcase connectionInitRfc:connectionL2capInit();break;
#endifcase connectionInitL2cap:connectionUdpInit();break;case connectionInitUdp:connectionTcpInit();break;case connectionInitTcp:connectionSdpInit(&theCm.sdpState);break;case connectionInitSdp: connectionVersionInit();break;case connectionInitVer:connectionSmInit(theCm.infoState.version,&theCm.smState,theCm.flags);break;case connectionInitSm:theCm.smState.noDevices = connectionAuthInit();break;case connectionInitComplete:/* We're ready! */                default:break;}}
}
  • 2.3.6 接下来第二次进入connectionBluestackHandler这个函数,只不过此时的状态已经更改为theCm.state = connectionInitialising;所以进入的函数为case connectionInitialising: 
    connectionBluestackHandlerInitialising(theCm, id, message); 
    break;
  • 2.3.7 connectionBluestackHandlerInitialising函数分析,此时的id为CL_INTERNAL_INIT_TIMEOUT_IND
<pre name="code" class="cpp">static void connectionBluestackHandlerInitialising(connectionState *theCm, MessageId id, Message message)
{/* Depending upon the message id...*/switch (id){case CL_INTERNAL_INIT_CFM:PRINT(("CL_INTERNAL_INIT_CFM\n"));connectionHandleInternalInit(((CL_INTERNAL_INIT_CFM_T*)message)->state);break;case CL_INTERNAL_INIT_TIMEOUT_IND:/*所以会执行下面的语句*/PRINT(("CL_INTERNAL_INIT_TIMEOUT_IND\n"));(void)MessageCancelFirst(&theCm->task, CL_INTERNAL_INIT_CFM);SET_CM_STATE(connectionUninitialised);connectionSendInitCfm(theCm->theAppTask, fail, bluetooth_unknown);/*这个函数是个重点,关注它的第一个参数为最重要的那个任务*/break;case CL_INTERNAL_SM_INIT_REQ:PRINT(("CL_INTERNAL_SM_INIT_REQ\n"));handleSecurityInitReq(&theCm->infoState, (CL_INTERNAL_SM_INIT_REQ_T *)message);break;case CL_INTERNAL_DM_READ_LOCAL_VERSION_REQ:PRINT(("CL_INTERNAL_DM_READ_LOCAL_VERSION_REQ\n"));connectionHandleReadLocalVersionRequest(&theCm->infoState, (CL_INTERNAL_DM_READ_LOCAL_VERSION_REQ_T *)message);break;case CL_INTERNAL_DM_SET_BT_VERSION_REQ:PRINT(("CL_INTERNAL_DM_SET_BT_VERSION_REQ\n"));connectionHandleSetBtVersionReq(&theCm->infoState, (CL_INTERNAL_DM_SET_BT_VERSION_REQ_T *)message);break;default:/* Prims we are not handling - for now panic the app */handleUnexpected(connectionUnhandledMessage, theCm->state, id);break;}
}
  • 2.3.8 回不去了 好像分析有误^0^………………..接着看connectionSendInitCfm函数
<pre name="code" class="cpp">void connectionSendInitCfm(Task task, connection_lib_status status, cl_dm_bt_version version)
{    MAKE_CL_MESSAGE(CL_INIT_CFM);message->status = status;//这里这个是failmessage->version = version;//版本的话没有bluetooth_unknown/*这个函数是重点,这个task是最重要的任务,所以会往上面返回一个没有初始化成功的标志*/MessageSend(task, CL_INIT_CFM, message);/* Cancel initialisation timeout */if(status == success)(void) MessageCancelFirst(connectionGetCmTask(), CL_INTERNAL_INIT_TIMEOUT_IND);
}

汗啊,分析了一遍结果发现到头来初始化失败了啊!! 
莫急,有没有注意到我上面说的那个时间很重要的参数,没错就是在这里,当这个时间到之后,确实会发送初始化失败,但是如果底层初始化成功的话这个消息将被取消,不会发往上面,其实程序看到这里的话,应该知道当状态变为初始化完成时,会向上面发送成功的标志,应该说流程大致有个印象,对于具体的其状态是怎样切换成初始化完成的,这个有待后面研究,目前我也不是很懂。

3.几个需要重要关注的地方

  • 结构体的理解是个重点
  • 连接库初始化的过程中状态的切换是个重点:这个没有解决!!! 
    百度文档搜索到一篇不错的文档: 
    注:参考文档,百度文档的对sink流程的分析–CSR ADK sink理解
转载:http://blog.csdn.net/code_warry/article/details/50519113

csr8670--sink工程的大致工作流程分析(以speaker为例)一相关推荐

  1. 【转载】csr8670--sink工程的大致工作流程分析(以speaker为例)二

    csr8670--sink工程的大致工作流程分析(以speaker为例)二 1.编解码任务的初始化 继续接着流程一分析: 1.1 当连接初始化完成之后,如下所示会调用编解码的初始化任务:这个编解码的任 ...

  2. csr8670--sink工程的大致工作流程分析(以speaker为例)二

    1.编解码任务的初始化 继续接着流程一分析: 1.1 当连接初始化完成之后,如下所示会调用编解码的初始化任务:这个编解码的任务作用是什么? <code class="hljs coff ...

  3. 16.U-boot的工作流程分析-2440

    16.U-boot的工作流程分析-2440 分析的流程: 程序入口 第一阶段程序分析 第二阶段程序分析 2440开发板: 1.uboot的入口: 要看uboot工程的入口,首先打开顶层目录的Makef ...

  4. K8S架构设计及工作流程分析

    Kubernetes架构设计 核心组件 api server 功能 controller manager 负责维护集群的状态 scheduler 负责资源的调度按照预定的调度策略将Pod调度到相应的机 ...

  5. kafka的基本概念和工作流程分析

    为什么需要消息队列 周末无聊刷着手机,某宝网APP突然蹦出来一条消息"为了回馈老客户,女朋友买一送一,活动仅限今天!".买一送一还有这种好事,那我可不能错过!忍不住立马点了去.于是 ...

  6. 【SemiDrive源码分析】【X9芯片启动流程】14 - freertos_safetyos目录Cortex-R5 SafetyOS/RTOS工作流程分析

    [SemiDrive源码分析][X9芯片启动流程]14 - freertos_safetyos目录Cortex-R5 SafetyOS/RTOS工作流程分析 一.SafetyOS 工作流程分析 1. ...

  7. 你想要的系列:网络请求框架OkHttp3全解系列 - (二)OkHttp的工作流程分析

    Okhttp系列文章: 你想要的系列:网络请求框架OkHttp3全解系列 - (一)OkHttp的基本使用 你想要的系列:网络请求框架OkHttp3全解系列 - (二)OkHttp的工作流程分析 你想 ...

  8. Zygote工作流程分析

    Zygote 接收客户端创建进程的请求,使用JNI调用linux fork函数创建进程. Zygote是在Init进程中作为Service被启动的.Zygote进程的主体是:ZygoteInit. Z ...

  9. Android 7.0 WifiMonitor工作流程分析

    2019独角兽企业重金招聘Python工程师标准>>> 在wifi启动扫描的分析过程中,出现了多次WifiMonitor的操作,在此分析一下这个函数是如何工作的. 在Android的 ...

最新文章

  1. Deepmind最新研究:从图表示学习看算法推理
  2. 学网络好帮手:路由器模拟软件RouteSim3.31
  3. 基于ASP.Net Core开发的一套通用后台框架
  4. Lombok介绍、附比较好用的几种注释推荐
  5. iOS逆向工程(简单利用dumpdecrypted给ipa砸壳)
  6. 消息队列面试 - 如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性?
  7. 双系统的电脑中如何完美系统其中一个操作系统
  8. VS Code 的 Java 七月更新,新的重构特性
  9. java实验总结_java第一次实验总结第三周总结
  10. RabbitMq的基本认识和配置(一)
  11. Failed to connect to d.line-scdn.net port 443: Operation timed out
  12. 2020.10.1--PS--画笔色彩模式、画笔预设、自定义画笔
  13. orc识别 语音识别 云真机 内网穿透快速调研
  14. 老男孩教育教育46期 LIHAO
  15. java自习_java自习重点及自测
  16. PHP高性能编程-提高PHP速度-加速PHP执行-PHP性能优化实践
  17. 篮球英文术语翻译与解释 (以A至E为限)
  18. 珞珈一号01星(luojia1-01)的夜间灯光影像数据处理流程
  19. 微软裁员方式曝光:鼓励自愿退休 减少合同工
  20. Python安装方法

热门文章

  1. php微信公众点歌台,PHP实现微信公众平台音乐点播功能
  2. 微信小程序 - 音乐播放器源码
  3. echarts上加横线标线_Echarts地图添加引导线效果(labelLine)
  4. Oracle日志挖掘技术logminer
  5. 解决sublime text2字体显示模糊问题
  6. Facebook背后的软件
  7. Java最牛教材!阿里技术官整合的四大主流中间件笔记
  8. Ubuntu 系统备份为ISO
  9. vue 项目中 自动生成 二维码
  10. npm install安装失败,报错记录之The operation was rejected by your operating system. node-sass无法安装,且禁用淘宝镜像