1. cc3200主时钟80M,内部没有flash,必须外接SPI Flash。本次测试采用利尔达科技的CC3200的底板和模块(左边)。烧写连接VCC, GND, RXD, TXD, SOP2, RST这6根线即可完成下载。
2. 使用IAR工具打开工程,看下main代码,其中VStartSimpleLinkSpawnTask这个函数搞不明白是什么?SimpleLink是TI注册的一个商标,CC3200是CC3200SimpleLink?Wi-Fi
1 void main() 2 { 3 long lRetVal = -1; 4 // 板子初始化配置 5 BoardInit(); 6 // 引脚复用配置 7 PinMuxConfig(); 8 //初始化穿口 9 InitTerm(); 10 // 启动SimpleLink Host 11 lRetVal = VStartSimpleLinkSpawnTask(SPAWN_TASK_PRIORITY); 12 if(lRetVal < 0) 13 { 14 ERR_PRINT(lRetVal); 15 LOOP_FOREVER(); 16 } 17 // 启动 WlanAPMode 任务 18 lRetVal = osi_TaskCreate( WlanAPMode, 19 (const signed char*)"wireless LAN in AP mode", 20 OSI_STACK_SIZE, NULL, 1, NULL ); 21 if(lRetVal < 0) 22 { 23 ERR_PRINT(lRetVal); 24 LOOP_FOREVER(); 25 } 26 // 开始任务调度 27 osi_start(); 28 }
3. 深入第一个函数去看看做了什么,创建了一个队列和一个任务,目前不知道这个任务是什么用途,其次2048的任务空间是从哪里分配的,作为栈的空间,任务切换的时候保存任务的当前环境变量。
1 OsiReturnVal_e VStartSimpleLinkSpawnTask(unsigned portBASE_TYPE uxPriority) 2 { 3 xSimpleLinkSpawnQueue = xQueueCreate( slQUEUE_SIZE, sizeof( tSimpleLinkSpawnMsg ) ); 4 if(0 == xSimpleLinkSpawnQueue) 5 { 6 return OSI_OPERATION_FAILED; 7 } 8 if(pdPASS == xTaskCreate( vSimpleLinkSpawnTask, ( portCHAR * ) "SLSPAWN", 9 (2048/sizeof( portSTACK_TYPE )), NULL, uxPriority, &xSimpleLinkSpawnTaskHndl )) 10 { 11 return OSI_OK; 12 } 13 return OSI_OPERATION_FAILED; 14 }
4. 延伸一个问题,任务里面的临时变量和数据还有任务里面的malloc,是从任务创建时候分配的栈里面再分配的吗?书上说是堆栈空间,malloc是从堆里分配的,2048/sizeof( portSTACK_TYPE )单位是字,4个字节,所以实际要乘以4的。
5. STM32有2个栈指针,MSP,PSP,一个是系统堆栈指针MSP,一个是任务堆栈指针PSP,任务堆栈用来做什么?保存局部变量,函数嵌套,任务切换的时候保存内核寄存器(保存在栈的高地址)和任务当前的状态(局部变量保存在低地址)。堆栈大小应该怎么去计算。任务里面的局部变量是保存在任务的栈里面的。
6. 继续看这个代码,一直循环接收队列,tSimpleLinkSpawnMsg Msg;这个应该是给wifi网络处理器返回应用处理器的消息队列。这个结构体有2个参数,一个函数和一个数据,都是通过队列传送的。
1 void vSimpleLinkSpawnTask(void *pvParameters) 2 { 3 tSimpleLinkSpawnMsg Msg; 4 portBASE_TYPE ret=pdFAIL; 5 for(;;) 6 { 7 ret = xQueueReceive( xSimpleLinkSpawnQueue, &Msg, portMAX_DELAY ); 8 if(ret == pdPASS) 9 { 10 Msg.pEntry(Msg.pValue); 11 } 12 } 13 }
7. 看下AP模式的设置代码
void WlanAPMode( void *pvParameters ) { int iTestResult = 0; unsigned char ucDHCP; long lRetVal = -1; InitializeAppVariables(); //恢复成默认模式 lRetVal = ConfigureSimpleLinkToDefaultState(); if(lRetVal < 0) { if (DEVICE_NOT_IN_STATION_MODE == lRetVal) UART_PRINT("Failed to configure the device in its default state \n\r"); LOOP_FOREVER(); } UART_PRINT("Device is configured in default state \n\r"); //启动网络 lRetVal = sl_Start(NULL,NULL,NULL); if (lRetVal < 0) { UART_PRINT("Failed to start the device \n\r"); LOOP_FOREVER(); } UART_PRINT("Device started as STATION \n\r"); //配置成AP模式 if(lRetVal != ROLE_AP) { if(ConfigureMode(lRetVal) != ROLE_AP) { sl_Stop(SL_STOP_TIMEOUT); LOOP_FOREVER(); } } //AP模式下,是否获取到自己的IP地址 while(!IS_IP_ACQUIRED(g_ulStatus)) { //looping till ip is acquired } unsigned char len = sizeof(SlNetCfgIpV4Args_t); SlNetCfgIpV4Args_t ipV4 = {0}; // 获取网络配置 lRetVal = sl_NetCfgGet(SL_IPV4_AP_P2P_GO_GET_INFO,&ucDHCP,&len, (unsigned char *)&ipV4); if (lRetVal < 0) { UART_PRINT("Failed to get network configuration \n\r"); LOOP_FOREVER(); } //等待STA设备连接,并给STA分配IP地址 while(!IS_IP_LEASED(g_ulStatus)) { } //和STA设备建立TCP连接 lRetVal = BsdTcpClient(PORT_NUM); if(lRetVal < 0) { UART_PRINT("TCP Client failed\n\r"); LOOP_FOREVER(); } while(1); }
查看下AP模式的设置函数
1 static int ConfigureMode(int iMode) 2 { 3 char pcSsidName[33] = "cc3200_tcptest"; 4 long lRetVal = -1; 5 6 //设置为AP模式 7 lRetVal = sl_WlanSetMode(ROLE_AP); 8 ASSERT_ON_ERROR(lRetVal); 9 //设置AP模式的SSID 10 lRetVal = sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SSID, strlen(pcSsidName), 11 (unsigned char*)pcSsidName); 12 ASSERT_ON_ERROR(lRetVal); 13 14 UART_PRINT("Device is configured in AP mode\n\r"); 15 16 /* Restart Network processor */ 17 lRetVal = sl_Stop(SL_STOP_TIMEOUT); 18 19 // reset status bits 20 CLR_STATUS_BIT_ALL(g_ulStatus); 21 return sl_Start(NULL,NULL,NULL); 22 }
8. 这个工程包含了3个库文件,其中simplelink.a比较特殊,在SDK中找个这个相关工程并打开。问题是sl_start究竟是启动的什么?和wifi网络处理器怎么通信的?
1 $PROJ_DIR$/../../../simplelink/ewarm/OS/Exe/simplelink.a 2 $PROJ_DIR$/../../../driverlib/ewarm/Release/Exe/driverlib.a 3 $PROJ_DIR$/../../../oslib/ewarm/free_rtos/Exe/free_rtos.a
9. 继续下一步
1 _i16 sl_WlanSetMode(const _u8 mode) 2 { 3 _SlwlanSetModeMsg_u Msg; 4 Msg.Cmd.mode = mode; 5 VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlWlanSetModeCmdCtrl , &Msg, NULL)); 6 return (_i16)Msg.Rsp.status; 7 }
10. 研究下,应用处理器是怎么给wifi网络处理器发数据的,不过以下可能有错误的
1 //以sl_WlanSet为例子,以下层层调用,最后通过SPI接口发出 2 第1步:sl_WlanSet 3 第2步:VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlWlanSetModeCmdCtrl , &Msg, NULL)); 4 第3步:_SlDrvMsgWrite 5 第4步:NWP_IF_WRITE_CHECK 6 第5步:spi_Write 7 第6步:spi_Write_CPU
11. 用uniflash烧写测试一下,不过下次要花时间研究下CC3200的内存分配了,涉及到串口升级,OTA升级等
12. 需要在电脑上建立一个tcp server测试一下,以前测试CC3200的TCP传输速度只有100KB每秒不知道原因,有机会要再次测试一下。