1. BSP-board support package , 主要针对板子的底层做了支持。 用bsp接口调用底层硬件可以降低硬件相关性。 对于nordic平台来说,BSP的底层硬件主要关联到灯和按键,这部分定义在boards.h中根据编译选项关联到对应的板子h文件,我们自定义的板子为hy0628.h
板子的.h文件主要就是灯和按键的引脚关联和数量,状态等定义,这部分是基本的
// LEDs definitions for dev 0628
#define LEDS_NUMBER 3
#define B_LED 9
#define R_LED 7
#define G_LED 5
#define LEDS_LIST { B_LED, R_LED, G_LED }
#define B_LED_Toggle nrf_gpio_pin_toggle(B_LED)
#define R_LED_Toggle nrf_gpio_pin_toggle(R_LED)
#define G_LED_Toggle nrf_gpio_pin_toggle(G_LED)
#define BSP_LED_0 B_LED
#define BSP_LED_1 R_LED
#define BSP_LED_2 G_LED
#define LEDS_ACTIVE_STATE 0
#define BUTTONS_NUMBER 3
#define USR_KEY1 2
#define USR_KEY2 3
#define USR_KEY3 4
#define BUTTONS_LIST { USR_KEY1, USR_KEY2, USR_KEY3}
#define BUTTONS_ACTIVE_STATE 0
#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
#define BSP_BUTTON_0 USR_KEY1
#define BSP_BUTTON_1 USR_KEY2
#define BSP_BUTTON_2 USR_KEY3
2. bsp.h里定义了板级的标准事件
typedef enum
{
BSP_EVENT_NOTHING = 0, /**< Assign this event to an action to prevent the action from generating an event (disable the action). */
BSP_EVENT_DEFAULT, /**< Assign this event to an action to assign the default event to the action. */
BSP_EVENT_CLEAR_BONDING_DATA, /**< Persistent bonding data should be erased. */
BSP_EVENT_CLEAR_ALERT, /**< An alert should be cleared. */
BSP_EVENT_DISCONNECT, /**< A link should be disconnected. */
BSP_EVENT_ADVERTISING_START, /**< The device should start advertising. */
BSP_EVENT_ADVERTISING_STOP, /**< The device should stop advertising. */
BSP_EVENT_WHITELIST_OFF, /**< The device should remove its advertising whitelist. */
BSP_EVENT_BOND, /**< The device should bond to the currently connected peer. */
BSP_EVENT_RESET, /**< The device should reset. */
BSP_EVENT_SLEEP, /**< The device should enter sleep mode. */
BSP_EVENT_WAKEUP, /**< The device should wake up from sleep mode. */
BSP_EVENT_SYSOFF, /**< The device should enter system off mode (without wakeup). */
BSP_EVENT_DFU, /**< The device should enter DFU mode. */
BSP_EVENT_KEY_0, /**< Default event of the push action of BSP_BUTTON_0 (only if this button is present). */
BSP_EVENT_KEY_1, /**< Default event of the push action of BSP_BUTTON_1 (only if this button is present). */
BSP_EVENT_KEY_2, /**< Default event of the push action of BSP_BUTTON_2 (only if this button is present). */
BSP_EVENT_KEY_3, /**< Default event of the push action of BSP_BUTTON_3 (only if this button is present). */
BSP_EVENT_KEY_4, /**< Default event of the push action of BSP_BUTTON_4 (only if this button is present). */
BSP_EVENT_KEY_5, /**< Default event of the push action of BSP_BUTTON_5 (only if this button is present). */
BSP_EVENT_KEY_6, /**< Default event of the push action of BSP_BUTTON_6 (only if this button is present). */
BSP_EVENT_KEY_7, /**< Default event of the push action of BSP_BUTTON_7 (only if this button is present). */
BSP_EVENT_KEY_LAST = BSP_EVENT_KEY_7,
} bsp_event_t;
3. 按键也有按下触发,释放触发或长按
typedef struct
{
bsp_event_t push_event; /**< The event to fire on regular button press. */
bsp_event_t long_push_event; /**< The event to fire on long button press. */
bsp_event_t release_event; /**< The event to fire on button release. */
} bsp_button_event_cfg_t;
4. 问题来了,如何在触发事件--状态切换--响应事件之间建立关联关系呢?
先看主程序,很简单,初始化,然后就低功耗等待了,所以中断,时钟调度,状态切换等都交给bsp去干活了,主循环不需要执行什么。下一个问题是: 如果要自定义功能呢? 留待下个例程分解
int main(void)
{
clock_initialization();
uint32_t err_code = app_timer_init();
APP_ERROR_CHECK(err_code);
APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
NRF_LOG_DEFAULT_BACKENDS_INIT();
NRF_LOG_INFO("BSP example started.");
bsp_configuration();
while (true)
{
NRF_LOG_FLUSH();
__SEV();
__WFE();
__WFE();
// no implementation needed
}
}
应该BSP是有个timer来调度资源的,所以主程序一开始,先要clock配置和调用app_timer_init()
void clock_initialization()
{
NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
NRF_CLOCK->TASKS_LFCLKSTART = 1;
while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
{
// Do nothing.
}
}
app_timer_init()应该是标准函数,定义了rtc和overflow的处理
5. 来看bsp_configuration()干了啥
void bsp_configuration()
{
uint32_t err_code;
err_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_evt_handler);
APP_ERROR_CHECK(err_code);
}
调用了bsp_init(),这个是标准函数还是自定义? 在bsp.c里,建立了触发条件和事件之间的关联
uint32_t bsp_init(uint32_t type, bsp_event_callback_t callback)
{
uint32_t err_code = NRF_SUCCESS;
#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
m_indication_type = type;
#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
#if (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE)
m_registered_callback = callback;
// BSP will support buttons and generate events
if (type & BSP_INIT_BUTTONS)
{
uint32_t num;
for (num = 0; ((num < BUTTONS_NUMBER) && (err_code == NRF_SUCCESS)); num++)
{
err_code = bsp_event_to_button_action_assign(num, BSP_BUTTON_ACTION_PUSH, BSP_EVENT_DEFAULT);
}