TI 的OSAL做的很不错,不过看起来也挺费劲可能自己水平太差吧,网上买的谷雨的开发板觉得确实挺不错的。

做点学习笔记,首先是记录OSAL里执行的顺序流程,主要是task ,event,message

1,

APP_Main.c:

/* Initialize the operating system */
osal_init_system();

其中初始化了

// Initialize the system tasks.
osalInitTasks();

  1. /*********************************************************************
  2. * @fn osalInitTasks
  3. *
  4. * @brief This function invokes the initialization function for each task.
  5. *
  6. * @param void
  7. *
  8. * @return none
  9. */
  10. void osalInitTasks( void )
  11. {
  12. uint8 taskID = ;
  13.  
  14. tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
  15. osal_memset( tasksEvents, , (sizeof( uint16 ) * tasksCnt));
  16.  
  17. /* LL Task */
  18. LL_Init( taskID++ );
  19.  
  20. /* Hal Task */
  21. Hal_Init( taskID++ );
  22.  
  23. /* HCI Task */
  24. HCI_Init( taskID++ );
  25.  
  26. #if defined ( OSAL_CBTIMER_NUM_TASKS )
  27. /* Callback Timer Tasks */
  28. osal_CbTimerInit( taskID );
  29. taskID += OSAL_CBTIMER_NUM_TASKS;
  30. #endif
  31.  
  32. /* L2CAP Task */
  33. L2CAP_Init( taskID++ );
  34.  
  35. /* GAP Task */
  36. GAP_Init( taskID++ );
  37.  
  38. /* GATT Task */
  39. GATT_Init( taskID++ );
  40.  
  41. /* SM Task */
  42. SM_Init( taskID++ );
  43.  
  44. /* Profiles */
  45. GAPRole_Init( taskID++ );
  46. GAPBondMgr_Init( taskID++ );
  47.  
  48. GATTServApp_Init( taskID++ );
  49.  
  50. /* Application */
  51. SimpleBLEPeripheral_Init( taskID );
  52. }

osalInitTasks

这个很关键,这个函数在OSAL_APP.c,初始化了所有的task以及tasksEvents,用来存储每个task中的事件表。

tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));

2,task存放:

  1. // The order in this table must be identical to the task initialization calls below in osalInitTask.
  2. const pTaskEventHandlerFn tasksArr[] =
  3. {
  4. LL_ProcessEvent, // task 0
  5. Hal_ProcessEvent, // task 1
  6. HCI_ProcessEvent, // task 2
  7. #if defined ( OSAL_CBTIMER_NUM_TASKS )
  8. OSAL_CBTIMER_PROCESS_EVENT( osal_CbTimerProcessEvent ), // task 3
  9. #endif
  10. L2CAP_ProcessEvent, // task 4
  11. GAP_ProcessEvent, // task 5
  12. GATT_ProcessEvent, // task 6
  13. SM_ProcessEvent, // task 7
  14. GAPRole_ProcessEvent, // task 8
  15. GAPBondMgr_ProcessEvent, // task 9
  16. GATTServApp_ProcessEvent, // task 10
  17. SimpleBLEPeripheral_ProcessEvent // task 11
  18. };

tasksArr[]

OSAL_APP.c 之后程序的各任务函数都在这里。

typedef unsigned short (*pTaskEventHandlerFn)( unsigned char task_id, unsigned short event );

3,task,os启动

APP_Main.c:

/* Start OSAL */
osal_start_system(); // No Return from here

这里进入无限循环:

  1. void osal_start_system( void )
  2. {
  3. #if !defined ( ZBIT ) && !defined ( UBIT )
  4. for(;;) // Forever Loop
  5. #endif
  6. {
  7. osal_run_system();
  8. }
  9. }

osal_start_system

主要调用每个task判断在其中的osal_run_system

  1. /*********************************************************************
  2. * @fn osal_run_system
  3. *
  4. * @brief
  5. *
  6. * This function will make one pass through the OSAL taskEvents table
  7. * and call the task_event_processor() function for the first task that
  8. * is found with at least one event pending. If there are no pending
  9. * events (all tasks), this function puts the processor into Sleep.
  10. *
  11. * @param void
  12. *
  13. * @return none
  14. */
  15. void osal_run_system( void )
  16. {
  17. uint8 idx = ;
  18.  
  19. #ifndef HAL_BOARD_CC2538
  20. osalTimeUpdate();
  21. #endif
  22.  
  23. Hal_ProcessPoll();
  24.  
  25. do {
  26. if (tasksEvents[idx]) // Task is highest priority that is ready.
  27. {
  28. break;
  29. }
  30. } while (++idx < tasksCnt);
  31.  
  32. if (idx < tasksCnt)
  33. {
  34. uint16 events;
  35. halIntState_t intState;
  36.  
  37. HAL_ENTER_CRITICAL_SECTION(intState);
  38. events = tasksEvents[idx];
  39. tasksEvents[idx] = ; // Clear the Events for this task.
  40. HAL_EXIT_CRITICAL_SECTION(intState);
  41.  
  42. activeTaskID = idx;
  43. events = (tasksArr[idx])( idx, events );
  44. activeTaskID = TASK_NO_TASK;
  45.  
  46. HAL_ENTER_CRITICAL_SECTION(intState);
  47. tasksEvents[idx] |= events; // Add back unprocessed events to the current task.
  48. HAL_EXIT_CRITICAL_SECTION(intState);
  49. }
  50. #if defined( POWER_SAVING )
  51. else // Complete pass through all task events with no activity?
  52. {
  53. osal_pwrmgr_powerconserve(); // Put the processor/system into sleep
  54. }
  55. #endif
  56.  
  57. /* Yield in case cooperative scheduling is being used. */
  58. #if defined (configUSE_PREEMPTION) && (configUSE_PREEMPTION == 0)
  59. {
  60. osal_task_yield();
  61. }
  62. #endif
  63. }

osal_run_system

先按task id判断优先级在前的task跳出来,然后根据event来执行程序。所谓根据event来执行是在task的主函数中通过if来判断:

比如我现在看的SimpleBLEPeripheral_ProcessEvent()也就是我们的application task

  1. /*********************************************************************
  2. * @fn SimpleBLEPeripheral_ProcessEvent
  3. *
  4. * @brief Simple BLE Peripheral Application Task event processor. This function
  5. * is called to process all events for the task. Events
  6. * include timers, messages and any other user defined events.
  7. *
  8. * @param task_id - The OSAL assigned task ID.
  9. * @param events - events to process. This is a bit map and can
  10. * contain more than one event.
  11. *
  12. * @return events not processed
  13. */
  14. uint16 SimpleBLEPeripheral_ProcessEvent( uint8 task_id, uint16 events )
  15. {
  16.  
  17. VOID task_id; // OSAL required parameter that isn't used in this function
  18.  
  19. if ( events & SYS_EVENT_MSG )
  20. {
  21. uint8 *pMsg;
  22.  
  23. if ( (pMsg = osal_msg_receive( simpleBLEPeripheral_TaskID )) != NULL )
  24. {
  25. simpleBLEPeripheral_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );
  26.  
  27. // Release the OSAL message
  28. VOID osal_msg_deallocate( pMsg );
  29. }
  30.  
  31. // return unprocessed events
  32. return (events ^ SYS_EVENT_MSG);
  33. }
  34.  
  35. if ( events & SBP_START_DEVICE_EVT )
  36. {
  37. // Start the Device
  38. VOID GAPRole_StartDevice( &simpleBLEPeripheral_PeripheralCBs );
  39.  
  40. // Start Bond Manager
  41. VOID GAPBondMgr_Register( &simpleBLEPeripheral_BondMgrCBs );
  42.  
  43. // Set timer for first periodic event
  44. osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD );
  45.  
  46. return ( events ^ SBP_START_DEVICE_EVT );
  47. }
  48.  
  49. if ( events & SBP_PERIODIC_EVT )
  50. {
  51. // Restart timer
  52. if ( SBP_PERIODIC_EVT_PERIOD )
  53. {
  54. osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD );
  55. }
  56.  
  57. // Perform periodic application task
  58. performPeriodicTask();
  59.  
  60. return (events ^ SBP_PERIODIC_EVT);
  61. }
  62.  
  63. #if defined ( PLUS_BROADCASTER )
  64. if ( events & SBP_ADV_IN_CONNECTION_EVT )
  65. {
  66. uint8 turnOnAdv = TRUE;
  67. // Turn on advertising while in a connection
  68. GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &turnOnAdv );
  69.  
  70. return (events ^ SBP_ADV_IN_CONNECTION_EVT);
  71. }
  72. #endif // PLUS_BROADCASTER
  73.  
  74. // Discard unknown events
  75. return ;
  76. }

SimpleBLEPeripheral_ProcessEvent

看到先执行:SYS_EVENT_MSG然后是SBP_START_DEVICE_EVT

每个EVENT执行完就return保证不过多占用CPU,

// return unprocessed events
return (events ^ SYS_EVENT_MSG);

return之后又会回到osal_run_system循环

4,event插入:

先不说SYS_EVENT_MSG,

刚才的SBP_START_DEVICE_EVT是在初始化时候就插入的

osalInitTasks();中的void SimpleBLEPeripheral_Init( uint8 task_id )

  1. /*********************************************************************
  2. * @fn SimpleBLEPeripheral_Init
  3. *
  4. * @brief Initialization function for the Simple BLE Peripheral App Task.
  5. * This is called during initialization and should contain
  6. * any application specific initialization (ie. hardware
  7. * initialization/setup, table initialization, power up
  8. * notificaiton ... ).
  9. *
  10. * @param task_id - the ID assigned by OSAL. This ID should be
  11. * used to send messages and set timers.
  12. *
  13. * @return none
  14. */
  15. void SimpleBLEPeripheral_Init( uint8 task_id )
  16. {
  17. simpleBLEPeripheral_TaskID = task_id;
  18.  
  19. // Setup the GAP
  20. VOID GAP_SetParamValue( TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL );
  21.  
  22. // Setup the GAP Peripheral Role Profile
  23. {
  24. #if defined( CC2540_MINIDK )
  25. // For the CC2540DK-MINI keyfob, device doesn't start advertising until button is pressed
  26. uint8 initial_advertising_enable = FALSE;
  27. #else
  28. // For other hardware platforms, device starts advertising upon initialization
  29. uint8 initial_advertising_enable = TRUE;
  30. #endif
  31.  
  32. // By setting this to zero, the device will go into the waiting state after
  33. // being discoverable for 30.72 second, and will not being advertising again
  34. // until the enabler is set back to TRUE
  35. uint16 gapRole_AdvertOffTime = ;
  36.  
  37. uint8 enable_update_request = DEFAULT_ENABLE_UPDATE_REQUEST;
  38. uint16 desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
  39. uint16 desired_max_interval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
  40. uint16 desired_slave_latency = DEFAULT_DESIRED_SLAVE_LATENCY;
  41. uint16 desired_conn_timeout = DEFAULT_DESIRED_CONN_TIMEOUT;
  42.  
  43. // Set the GAP Role Parameters
  44. GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable );
  45. GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime );
  46.  
  47. GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData );
  48. GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData );
  49.  
  50. GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_ENABLE, sizeof( uint8 ), &enable_update_request );
  51. GAPRole_SetParameter( GAPROLE_MIN_CONN_INTERVAL, sizeof( uint16 ), &desired_min_interval );
  52. GAPRole_SetParameter( GAPROLE_MAX_CONN_INTERVAL, sizeof( uint16 ), &desired_max_interval );
  53. GAPRole_SetParameter( GAPROLE_SLAVE_LATENCY, sizeof( uint16 ), &desired_slave_latency );
  54. GAPRole_SetParameter( GAPROLE_TIMEOUT_MULTIPLIER, sizeof( uint16 ), &desired_conn_timeout );
  55. }
  56.  
  57. // Set the GAP Characteristics
  58. GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName );
  59.  
  60. // Set advertising interval
  61. {
  62. uint16 advInt = DEFAULT_ADVERTISING_INTERVAL;
  63.  
  64. GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MIN, advInt );
  65. GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MAX, advInt );
  66. GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MIN, advInt );
  67. GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MAX, advInt );
  68. }
  69.  
  70. // Setup the GAP Bond Manager
  71. {
  72. uint32 passkey = ; // passkey "000000"
  73. uint8 pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
  74. uint8 mitm = TRUE;
  75. uint8 ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
  76. uint8 bonding = TRUE;
  77. GAPBondMgr_SetParameter( GAPBOND_DEFAULT_PASSCODE, sizeof ( uint32 ), &passkey );
  78. GAPBondMgr_SetParameter( GAPBOND_PAIRING_MODE, sizeof ( uint8 ), &pairMode );
  79. GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof ( uint8 ), &mitm );
  80. GAPBondMgr_SetParameter( GAPBOND_IO_CAPABILITIES, sizeof ( uint8 ), &ioCap );
  81. GAPBondMgr_SetParameter( GAPBOND_BONDING_ENABLED, sizeof ( uint8 ), &bonding );
  82. }
  83.  
  84. // Initialize GATT attributes
  85. GGS_AddService( GATT_ALL_SERVICES ); // GAP
  86. GATTServApp_AddService( GATT_ALL_SERVICES ); // GATT attributes
  87. DevInfo_AddService(); // Device Information Service
  88. SimpleProfile_AddService( GATT_ALL_SERVICES ); // Simple GATT Profile
  89. #if defined FEATURE_OAD
  90. VOID OADTarget_AddService(); // OAD Profile
  91. #endif
  92.  
  93. // Setup the SimpleProfile Characteristic Values
  94. {
  95. uint8 charValue1 = ;
  96. uint8 charValue2 = ;
  97. uint8 charValue3 = ;
  98. uint8 charValue4 = ;
  99. uint8 charValue5[SIMPLEPROFILE_CHAR5_LEN] = { , , , , };
  100. SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR1, sizeof ( uint8 ), &charValue1 );
  101. SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR2, sizeof ( uint8 ), &charValue2 );
  102. SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR3, sizeof ( uint8 ), &charValue3 );
  103. SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR4, sizeof ( uint8 ), &charValue4 );
  104. SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN, charValue5 );
  105. }
  106.  
  107. #if defined( CC2540_MINIDK )
  108.  
  109. SK_AddService( GATT_ALL_SERVICES ); // Simple Keys Profile
  110.  
  111. // Register for all key events - This app will handle all key events
  112. RegisterForKeys( simpleBLEPeripheral_TaskID );
  113.  
  114. // makes sure LEDs are off
  115. HalLedSet( (HAL_LED_1 | HAL_LED_2), HAL_LED_MODE_OFF );
  116.  
  117. // For keyfob board set GPIO pins into a power-optimized state
  118. // Note that there is still some leakage current from the buzzer,
  119. // accelerometer, LEDs, and buttons on the PCB.
  120.  
  121. P0SEL = ; // Configure Port 0 as GPIO
  122. P1SEL = ; // Configure Port 1 as GPIO
  123. P2SEL = ; // Configure Port 2 as GPIO
  124.  
  125. P0DIR = 0xFC; // Port 0 pins P0.0 and P0.1 as input (buttons),
  126. // all others (P0.2-P0.7) as output
  127. P1DIR = 0xFF; // All port 1 pins (P1.0-P1.7) as output
  128. P2DIR = 0x1F; // All port 1 pins (P2.0-P2.4) as output
  129.  
  130. P0 = 0x03; // All pins on port 0 to low except for P0.0 and P0.1 (buttons)
  131. P1 = ; // All pins on port 1 to low
  132. P2 = ; // All pins on port 2 to low
  133.  
  134. #endif // #if defined( CC2540_MINIDK )
  135.  
  136. #if (defined HAL_LCD) && (HAL_LCD == TRUE)
  137.  
  138. #if defined FEATURE_OAD
  139. #if defined (HAL_IMAGE_A)
  140. HalLcdWriteStringValue( "BLE Peri-A", OAD_VER_NUM( _imgHdr.ver ), , HAL_LCD_LINE_1 );
  141. #else
  142. HalLcdWriteStringValue( "BLE Peri-B", OAD_VER_NUM( _imgHdr.ver ), , HAL_LCD_LINE_1 );
  143. #endif // HAL_IMAGE_A
  144. #else
  145. HalLcdWriteString( "BLE Peripheral", HAL_LCD_LINE_1 );
  146. #endif // FEATURE_OAD
  147.  
  148. #endif // (defined HAL_LCD) && (HAL_LCD == TRUE)
  149.  
  150. // Register callback with SimpleGATTprofile
  151. VOID SimpleProfile_RegisterAppCBs( &simpleBLEPeripheral_SimpleProfileCBs );
  152.  
  153. // Enable clock divide on halt
  154. // This reduces active current while radio is active and CC254x MCU
  155. // is halted
  156. HCI_EXT_ClkDivOnHaltCmd( HCI_EXT_ENABLE_CLK_DIVIDE_ON_HALT );
  157.  
  158. #if defined ( DC_DC_P0_7 )
  159.  
  160. // Enable stack to toggle bypass control on TPS62730 (DC/DC converter)
  161. HCI_EXT_MapPmIoPortCmd( HCI_EXT_PM_IO_PORT_P0, HCI_EXT_PM_IO_PORT_PIN7 );
  162.  
  163. #endif // defined ( DC_DC_P0_7 )
  164.  
  165. // Setup a delayed profile startup
  166. osal_set_event( simpleBLEPeripheral_TaskID, SBP_START_DEVICE_EVT );
  167.  
  168. }

SimpleBLEPeripheral_Init

最后一句:

// Setup a delayed profile startup
osal_set_event( simpleBLEPeripheral_TaskID, SBP_START_DEVICE_EVT );

5,message:

只能简单做个笔记不细说它的功能作用,我们在SimpleBLEPeripheral_ProcessEvent的SYS_EVENT_MSG中看到的,一般message在这发送的是key事件,传回key的值这样可以带一些自己的data,不像event只是标志。

至于这个key的来源:

1,之前已经初始化过hal_key,在前面可以找到,

/* Initialize Key stuff */
OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;
//OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE;
HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);

SimpleBLEPeripheral_Init中注册,把key和task联系起来,也就是key按了之后通知哪个task

// Register for all key events - This app will handle all key events
RegisterForKeys( simpleBLEPeripheral_TaskID );

2,执行顺序首先是按键引起中断:

一旦有中断发生,中断函数首先跳转到
HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )
{
  halProcessKeyInterrupt();
 
………
}

hal_key.c中void halProcessKeyInterrupt (void)

  1. /**************************************************************************************************
  2. * @fn halProcessKeyInterrupt
  3. *
  4. * @brief Checks to see if it's a valid key interrupt, saves interrupt driven key states for
  5. * processing by HalKeyRead(), and debounces keys by scheduling HalKeyRead() 25ms later.
  6. *
  7. * @param
  8. *
  9. * @return
  10. **************************************************************************************************/
  11. void halProcessKeyInterrupt (void)
  12. {
  13. bool valid=FALSE;
  14.  
  15. #if defined ( CC2540_MINIDK )
  16. if( HAL_KEY_SW_1_PXIFG & HAL_KEY_SW_1_BIT) /* Interrupt Flag has been set by SW1 */
  17. {
  18. HAL_KEY_SW_1_PXIFG = ~(HAL_KEY_SW_1_BIT); /* Clear Interrupt Flag */
  19. valid = TRUE;
  20. }
  21.  
  22. if (HAL_KEY_SW_2_PXIFG & HAL_KEY_SW_2_BIT) /* Interrupt Flag has been set by SW2 */
  23. {
  24. HAL_KEY_SW_2_PXIFG = ~(HAL_KEY_SW_2_BIT); /* Clear Interrupt Flag */
  25. valid = TRUE;
  26. }
  27. #else
  28. if (HAL_KEY_SW_6_PXIFG & HAL_KEY_SW_6_BIT) /* Interrupt Flag has been set */
  29. {
  30. HAL_KEY_SW_6_PXIFG = ~(HAL_KEY_SW_6_BIT); /* Clear Interrupt Flag */
  31. valid = TRUE;
  32. }
  33.  
  34. if (HAL_KEY_JOY_MOVE_PXIFG & HAL_KEY_JOY_MOVE_BIT) /* Interrupt Flag has been set */
  35. {
  36. HAL_KEY_JOY_MOVE_PXIFG = ~(HAL_KEY_JOY_MOVE_BIT); /* Clear Interrupt Flag */
  37. valid = TRUE;
  38. }
  39. #endif
  40. if (valid)
  41. {
  42. osal_start_timerEx (Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_DEBOUNCE_VALUE);
  43. }
  44. }

void halProcessKeyInterrupt (void)

判断是否中断,中断清楚标志,最后osal_start_timerEx (Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_DEBOUNCE_VALUE);

这是告诉Hal_TaskID 的task,发生了HAL_KEY_EVENT,延时HAL_KEY_DEBOUNCE_VALUE之后执行,这里延时个人认为是去抖动

3,

Hal_TaskID 的task在hal_drive.c中

uint16 Hal_ProcessEvent( uint8 task_id, uint16 events )

if (events & HAL_KEY_EVENT)
{
#if (defined HAL_KEY) && (HAL_KEY == TRUE)
/* Check for keys */
HalKeyPoll();

/* if interrupt disabled, do next polling */
if (!Hal_KeyIntEnable)
{
osal_start_timerEx( Hal_TaskID, HAL_KEY_EVENT, 100);
}
#endif
return events ^ HAL_KEY_EVENT;
}

执行了HalKeyPoll();函数,注意后面if如果没有中断则100ms后再启动这个event,没有中断就是在这轮询

4,HalKeyPoll()

  1. /**************************************************************************************************
  2. * @fn HalKeyPoll
  3. *
  4. * @brief Called by hal_driver to poll the keys
  5. *
  6. * @param None
  7. *
  8. * @return None
  9. **************************************************************************************************/
  10. void HalKeyPoll (void)
  11. {
  12. uint8 keys = ;
  13. uint8 notify = ;
  14. #if defined (CC2540_MINIDK)
  15. if (!(HAL_KEY_SW_1_PORT & HAL_KEY_SW_1_BIT)) /* Key is active low */
  16. {
  17. keys |= HAL_KEY_SW_1;
  18. }
  19. if (!(HAL_KEY_SW_2_PORT & HAL_KEY_SW_2_BIT)) /* Key is active low */
  20. {
  21. keys |= HAL_KEY_SW_2;
  22. }
  23. #else
  24. if (!(HAL_KEY_SW_6_PORT & HAL_KEY_SW_6_BIT)) /* Key is active low */
  25. {
  26. keys |= HAL_KEY_SW_6;
  27. }
  28.  
  29. if ((HAL_KEY_JOY_MOVE_PORT & HAL_KEY_JOY_MOVE_BIT)) /* Key is active HIGH */
  30. {
  31. keys = halGetJoyKeyInput();
  32. }
  33. #endif
  34.  
  35. /* If interrupts are not enabled, previous key status and current key status
  36. * are compared to find out if a key has changed status.
  37. */
  38. if (!Hal_KeyIntEnable)
  39. {
  40. if (keys == halKeySavedKeys)
  41. {
  42. /* Exit - since no keys have changed */
  43. return;
  44. }
  45. else
  46. {
  47. notify = ;
  48. }
  49. }
  50. else
  51. {
  52. /* Key interrupt handled here */
  53. if (keys)
  54. {
  55. notify = ;
  56. }
  57. }
  58.  
  59. /* Store the current keys for comparation next time */
  60. halKeySavedKeys = keys;
  61.  
  62. /* Invoke Callback if new keys were depressed */
  63. if (notify && (pHalKeyProcessFunction))
  64. {
  65. (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);
  66.  
  67. }
  68. }

HalKeyPoll()

前面是判断哪个被按下,最后一句很关键:

/* Invoke Callback if new keys were depressed */
if (notify && (pHalKeyProcessFunction))
{
(pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);

}

回调函数这时候启动OnBoard_KeyCallback这在之前的初始化时候和pHalKeyProcessFunction挂钩

5,

  1. /*********************************************************************
  2. * @fn OnBoard_KeyCallback
  3. *
  4. * @brief Callback service for keys
  5. *
  6. * @param keys - keys that were pressed
  7. * state - shifted
  8. *
  9. * @return void
  10. *********************************************************************/
  11. void OnBoard_KeyCallback ( uint8 keys, uint8 state )
  12. {
  13. uint8 shift;
  14. (void)state;
  15.  
  16. // shift key (S1) is used to generate key interrupt
  17. // applications should not use S1 when key interrupt is enabled
  18. shift = (OnboardKeyIntEnable == HAL_KEY_INTERRUPT_ENABLE) ? false : ((keys & HAL_KEY_SW_6) ? true : false);
  19.  
  20. if ( OnBoard_SendKeys( keys, shift ) != SUCCESS )
  21. {
  22. // Process SW1 here
  23. if ( keys & HAL_KEY_SW_1 ) // Switch 1
  24. {
  25. }
  26. // Process SW2 here
  27. if ( keys & HAL_KEY_SW_2 ) // Switch 2
  28. {
  29. }
  30. // Process SW3 here
  31. if ( keys & HAL_KEY_SW_3 ) // Switch 3
  32. {
  33. }
  34. // Process SW4 here
  35. if ( keys & HAL_KEY_SW_4 ) // Switch 4
  36. {
  37. }
  38. // Process SW5 here
  39. if ( keys & HAL_KEY_SW_5 ) // Switch 5
  40. {
  41. }
  42. // Process SW6 here
  43. if ( keys & HAL_KEY_SW_6 ) // Switch 6
  44. {
  45. }
  46. }
  47.  
  48. /* If any key is currently pressed down and interrupt
  49. is still enabled, disable interrupt and switch to polling */
  50. if( keys != )
  51. {
  52. if( OnboardKeyIntEnable == HAL_KEY_INTERRUPT_ENABLE )
  53. {
  54. OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE;
  55. HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);
  56. }
  57. }
  58. /* If no key is currently pressed down and interrupt
  59. is disabled, enable interrupt and turn off polling */
  60. else
  61. {
  62. if( OnboardKeyIntEnable == HAL_KEY_INTERRUPT_DISABLE )
  63. {
  64. OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;
  65. HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);
  66. }
  67. }
  68. }

OnBoard_KeyCallback

在on_board.c中

主要的一句:OnBoard_SendKeys( keys, shift )这里发送给了前台task

  1. *********************************************************************
  2. * @fn OnBoard_SendKeys
  3. *
  4. * @brief Send "Key Pressed" message to application.
  5. *
  6. * @param keys - keys that were pressed
  7. * state - shifted
  8. *
  9. * @return status
  10. *********************************************************************/
  11. uint8 OnBoard_SendKeys( uint8 keys, uint8 state )
  12. {
  13. keyChange_t *msgPtr;
  14.  
  15. if ( registeredKeysTaskID != NO_TASK_ID )
  16. {
  17. // Send the address to the task
  18. msgPtr = (keyChange_t *)osal_msg_allocate( sizeof(keyChange_t) );
  19. if ( msgPtr )
  20. {
  21. msgPtr->hdr.event = KEY_CHANGE;
  22. msgPtr->state = state;
  23. msgPtr->keys = keys;
  24.  
  25. osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr );
  26. }
  27. return ( SUCCESS );
  28. }
  29. else
  30. return ( FAILURE );
  31. }

OnBoard_SendKeys

osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr );

registeredKeysTaskID之前初始化注册ID我们的apptask,并且这个函数osal_msg_send会触发一个SYS_EVENT_MSG这样就到了前台

6,msg的各种结构:

  1. static void simpleBLEPeripheral_ProcessOSALMsg( osal_event_hdr_t *pMsg )
  2. {
  3. switch ( pMsg->event )
  4. {
  5. #if defined( CC2540_MINIDK )
  6. case KEY_CHANGE:
  7. simpleBLEPeripheral_HandleKeys( ((keyChange_t *)pMsg)->state, ((keyChange_t *)pMsg)->keys );
  8. break;
  9. #endif // #if defined( CC2540_MINIDK )
  10.  
  11. default:
  12. // do nothing
  13. break;
  14. }
  15. }

simpleBLEPeripheral_ProcessOSALMsg

typedef struct
{
uint8 event;
uint8 status;
} osal_event_hdr_t;

到了key:

typedef struct
{
osal_event_hdr_t hdr;
uint8 state; // shift
uint8 keys; // keys
} keyChange_t;

最开始时候:

uint8 *pMsg;

if ( (pMsg = osal_msg_receive( simpleBLEPeripheral_TaskID )) != NULL )
{
simpleBLEPeripheral_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );

// Release the OSAL message
VOID osal_msg_deallocate( pMsg );
}

注意osal_msg_deallocate释放这样就算走完了一遍key

以及整个工程的流程了,花了两三天时间看完的,感谢谷雨资料

TI BLE STACK - OSAL的更多相关文章

  1. TI BLE协议栈软件框架分析

    看源代码的时候,一般都是从整个代码的入口处开始,TI  BLE 协议栈源码也不例外.它的入口main()函数就是整个程序的入口,由系统上电时自动调用. 它主要做了以下几件事情: (一)底层硬件初始化配 ...

  2. TI BLE: Advertisement

    #define GAPROLE_ADVERT_ENABLED 0x305 //!< Enable/Disable Advertising. Read/Write. Size is uint8. ...

  3. TI BLE CC2541的SPI主模式

    SPI就是用4条线来串行传输数据, 2541只能用模拟的方式用GPIO来做. //*********************************************************** ...

  4. TI BLE:SCAN

    主机会运行SCAN来搜寻广播中的设备 运行函数: GAPCentralRole_StartDiscovery( DEFAULT_DISCOVERY_MODE, DEFAULT_DISCOVERY_AC ...

  5. TI BLE CC2541的通讯协议.

    包类型: 01命令/02数据/03应答消息 开始标志FF/本数据包长度(注意是16进制)/校验码/包ID/包类型01: 表示是命令/01表示下面要开始传输/03字符串编号/字符串长度/结束位FEFF  ...

  6. TI BLE CC2541的I2C主模式

    由于要写TM1680, 写命令跟写数据, 所以需要使用CC2541的I2C, 2541是有硬件I2C的. tm1680.c: #include "tm1680.h" //TM168 ...

  7. TI BLE:读本机地址

    uint8 ownAddress[B_ADDR_LEN];  //B_ADDR_LEN=6GAPRole_GetParameter(GAPROLE_BD_ADDR, ownAddress); #def ...

  8. TI BLE : GAP Bond Manager

    // Setup the GAP Bond Manager { uint32 passkey = 0; // passkey "000000" uint8 pairMode = G ...

  9. 让BLE设备的名称包含MAC地址

    对于研发和测试BLE来说,经常看到同名的设备,是极为不方便的,一大堆设备同时上电会让同事不知道哪一个设备才是自己真正想操作的目标.再说一下小米手环,家中有三支小米手环,打开设备搜索全是“MI”,都不知 ...

随机推荐

  1. Anaconda基本用法

    Anaconda基本用法 conda info --envs/(-e) // 查看当前的环境变量 conda create -n py36(环境的名称,随意) python=3.6(指定版本) //  ...

  2. python flask获取微信用户信息流程

    需要了解的几个url 用户第一次访问时的url,包含以下几个参数 https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID& ...

  3. Directory获取方式

    1) FSDirectory.open FSDirectory.open()会以最合适的方式来获取一个Directory对象. 2) RAMDirectory 可以将磁盘中的索引加载到内存中,访问速度 ...

  4. 自动生成 serialVersionUID 的设置

    1 把鼠标放在类名上,会出现小灯泡的形状 点击 Add ‘serialVersionUID’ field... 即可生成 如果鼠标放在类名上没有出现 Add ‘serialVersionUID’ fi ...

  5. python接口测试之Http请求(三)

    python的强大之处在于提供了很多的标准库,这些标准库可以直接调用,本节部分,重点学习和总结在 接口测试中Python的Http请求的库的学习. 首先来看httplib,官方的解释为:本模块定义了类 ...

  6. Linux find常用命令

    今天研究一下find的一些常用的命令. find格式:find filepath [-option] [-print|-exec|-ok...] 其中常用的option主要有 -type d|f|s| ...

  7. 18.9.22 noip模拟赛

    此题为找规律.期望100 实际100 #include<cstdio> #include<cstring> #include<iostream> #include& ...

  8. Servlet实现国际化

    以下内容引用自http://wiki.jikexueyuan.com/project/servlet/internationalization.html: 三个重要术语: 国际化(i18n):这意味着 ...

  9. 谈论javascript闭包

    闭包看似很简单,其实牵扯了很多东西,例如:上下文作用域(事件处理程序).内存占用.局部以及全局变量.回调函数以及编程模式等 首先我们谈论一个问题,为什么需要闭包? 1.var全局定义(全局污染)- 指 ...

  10. android 加密手机完毕后待机两分钟出现有频率的杂音

    这个音效是code里面主动加的,是为了提醒end user输入PIN的一个提示音,也标志着加密手机动作的完毕. 详细位置是在alps\packages\apps\Settings\src\com\an ...