pb03f,osal基本学习
-
OSAL主要是这样一种机制,一种任务分配资源的机制,从而形成了一个简单多任务的操作系统。首先,osal初始化系统,包括软件系统初始化和资源初始化.其中软件系统初始化就是初始化一些变量,比如osal重要的组成部分任务表,任务结构体和序列号.资源初始化主要包括内存,中断,NV等各种设备模块资源.这就和我们嵌入式系统中的RTOS操作系统μC/OS-II有了很大的相似处。μC/OS-II中也是通过建立任务把一个问题进行分解,任务之间可以通过消息队列的方式进行通信。
-
接着,osal通过osal_add_task添加任务到任务表中,形成一个任务链表.这个任务链表是以任务的优先级先后排序的.优先级高的排在前,低者排于后.
-
最后,开始运行系统,系统是以一个死循环的形式工作的.在循环体当中不断地检测各个任务,看是否要运行等.这就相当于我们平时用的linux和window等多任务系统,把CPU分成N个时间片(有多少任务就分成多少时间片),只要处理频率高,就相当于多任务同时运行了 。
软件
- keil5
- PhyPlusKit
代码地址
https://github.com/xuhongv/PHY6252_6222_SDK/tree/main/my_examples/peripheral/gpio
项目结构
项目结构说明
- main和jump_table 都不需要自己去修改
- main可以改一下配置 主要作用是配置硬件初始化 和 配置脚电平
- jump_table 主要是配置报错的时候使用
- gpio_main 也不怎么需要更改 但可以看做程序入口
- 主要是 gpio_demo和osal_gpio 这两个文件
- gpio_demo制作方法处理(*)
- osal_gpio文件注册方法(*)
代码文件
- OSAL_gpio.c
#include "OSAL.h"
#include "OSAL_Tasks.h"
#include "ll.h"
/* Application */
#include "gpio_demo.h"
/*********************************************************************
GLOBAL VARIABLES
*/
// The order in this table must be identical to the task initialization calls below in osalInitTask.
// 这个数组包含了所有任务的事件处理函数。数组中的函数顺序必须与后续任务初始化函数调用顺序一致。
const pTaskEventHandlerFn tasksArr[] =
{
LL_ProcessEvent, // 链路层事件处理函数。
Blink_ProcessEvent, // 用于处理GPIO示例代码的事件。
};
//这个变量表示任务数组中的任务数量。通过计算tasksArr数组的大小除以单个元素的大小得到。
const uint8 tasksCnt = sizeof( tasksArr ) / sizeof( tasksArr[0] ); //
// 这是一个指向任务事件数组的指针,每个任务都有对应的事件。
uint16* tasksEvents;
/*********************************************************************
FUNCTIONS
*********************************************************************/
/*********************************************************************
@fn osalInitTasks
@brief This function invokes the initialization function for each task.
@param void
@return none
*/
void osalInitTasks( void )
{
uint8 taskID = 0;
// 使用OSAL内存分配函数为任务事件数组分配内存。
tasksEvents = (uint16*)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
// 使用OSAL内存设置函数将任务事件数组初始化为0。
osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));
//调用每个任务的初始化函数,并传递任务ID。任务ID从0开始,每初始化一个任务就递增一次。
LL_Init( taskID++);
Blink_Init(taskID);
}
/*********************************************************************
*********************************************************************/
- gpio_demo.c
/*
* @Author: xuhongv | 半颗心脏 xuhongv@yeah.net
* @Date: 2022-11-23 17:32:11
* @LastEditors: xuhongv | 半颗心脏 xuhongv@yeah.net
* @LastEditTime: 2022-11-24 10:38:25
* @FilePath: \PHY6252_6222_SDK\my_examples\peripheral\gpio\Source\gpio_demo.c
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
#include "OSAL.h"
#include "gpio_demo.h"
#include "log.h"
#include "gpio.h"
#include "clock.h"
#include "pwrmgr.h"
#include "error.h"
#include "key.h"
static uint8 Blink_TaskID; //任务ID,用于标识当前任务。
static uint8 Blink_Task_EVT = 0xF0; //任务事件,用于标识具体的事件,0xF0是事件的掩码。
// for ai-thinker PB-03-Kit GREEN LED
#define LED_GPIO GPIO_P11 //定义了用于控制LED的GPIO引脚(GPIO_P11)。
void LED_Toggle(GPIO_Pin_e pin)
{
hal_gpio_pin_init(pin, OEN); 初始化GPIO引脚,设置为输出模式
if (hal_gpio_read(pin)) 读取GPIO引脚状态
hal_gpio_write(pin, 0); // // 如果引脚为高电平,则写低电平
else
hal_gpio_write(pin, 1); // 如果引脚为低电平,则写高电平
}
void Blink_Init(uint8 task_id)
{
LOG("%s task_id=%d \n", __FUNCTION__, task_id); // 打印日志,记录函数名和任务ID
Blink_TaskID = task_id; // 设置任务ID
// LED 转换 // 初始化LED引脚,设置为输出模式,并点亮LED
hal_gpio_pin_init(LED_GPIO, OEN);
hal_gpio_write(LED_GPIO, 1);
// 启动一个定时器,1000毫秒后触发Blink_Task_EVT事件
osal_start_timerEx(Blink_TaskID, Blink_Task_EVT, 1000);
}
uint16 Blink_ProcessEvent(uint8 task_id, uint16 events)
{
if (task_id != Blink_TaskID)
{
return 0; // 如果任务ID不匹配,则返回0
}
if (events & Blink_Task_EVT)
{
// LED 转换 // 切换LED状态
LED_Toggle(LED_GPIO);
//延迟一秒
WaitMs(1000);
LOG("%s \n", __FUNCTION__); // 打印日志,记录函数名
// 重新启动定时器,2000毫秒后触发Blink_Task_EVT事件
osal_start_timerEx(Blink_TaskID, Blink_Task_EVT, 2000);
return (events ^ Blink_Task_EVT); // 清除处理过的事件
}
return 0;
}
- gpio_Main.c
/*
* @Author: xuhongv | 半颗心脏 xuhongv@yeah.net
* @Date: 2022-11-23 17:22:43
* @LastEditors: xuhongv | 半颗心脏 xuhongv@yeah.net
* @LastEditTime: 2022-11-23 17:40:56
* @FilePath: \PHY6252_6222_SDK\my_examples\peripheral\gpio\Source\gpio_Main.c
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
/* OSAL */
#include "OSAL.h"
#include "OSAL_Tasks.h"
#include "OSAL_PwrMgr.h"
#include "osal_snv.h"
#include "ll_sleep.h"
#include "uart.h"
/**************************************************************************************************
FUNCTIONS
**************************************************************************************************/
#include "comdef.h"
#include "OSAL.h"
#include "OSAL_Tasks.h"
#include "OSAL_Timers.h"
#include "OSAL_PwrMgr.h"
#include "timer.h"
#include "ll_sleep.h"
#include "jump_function.h"
#include "global_config.h"
extern pwrmgr_attribute_t pwrmgr_attribute; //电源管理属性,用于管理设备的电源状态。
extern uint32 ll_remain_time; // 剩余时间变量,可能用于低功耗管理中的时间计算。
/*********************************************************************
EXTERNAL VARIABLES
*/
/**************************************************************************************************
@fn main
@brief Start of application.
@param none
@return none
**************************************************************************************************
*/
int app_main(void)
{
/* Initialize the operating system 这个函数用于初始化操作系统。它会设置操作系统所需的所有数据结构和状态。 */
osal_init_system();
//这个函数用于配置设备的电源管理属性。在这里,它被设置为电池供电模式(PWRMGR_BATTERY)。
osal_pwrmgr_device( PWRMGR_BATTERY );
/* Start OSAL */
// 这个函数启动操作系统的主循环。调用这个函数后,系统会进入无限循环,处理事件和任务,不会返回。
osal_start_system(); // No Return from here
return 0;
}
/**************************************************************************************************
CALL-BACKS
**************************************************************************************************/
/*************************************************************************************************
**************************************************************************************************/
- jump_table.c
#include "jump_function.h"
#include "global_config.h"
#include "OSAL_Tasks.h"
#include "rf_phy_driver.h"
#include "pwrmgr.h"
#include "gpio.h"
#include "timer.h"
#include "uart.h"
#include "log.h"
// 这些宏定义用于配置和定义硬件故障处理的相关信息和参数。例如,DEF_HARD_FAULT_LOG_DEBUG 表示是否启用硬件故障日志调试功能;
// DEF_HARD_FAULT_DUMP_SP_LEN 定义了堆栈转储的长度;
// FSID_HARD_FAULT_BASE 定义了硬件故障记录的基地址等。
#define DEF_HARD_FAULT_LOG_DEBUG (1)
#if( DEF_HARD_FAULT_FS_ENABLE)
#include "fs.h"
#endif
#define DEF_HARD_FAULT_DUMP_SP_LEN 256
#define MAX_FS_HARD_FAULT_REC_NUM 16 // should be 2**n
#define FSID_HARD_FAULT_BASE 0xFE00
#define FSID_HARD_FAULT_NUM (FSID_HARD_FAULT_BASE)
#define FSID_HARD_FAULT_CURRENT(x) (FSID_HARD_FAULT_BASE+1+((x)&(MAX_FS_HARD_FAULT_REC_NUM-1) ) )
#define FSID_REC_EXTRA_BUF_LEN 4 // for hf rec , 2 for osal event 1 for osal sys tick, 1 for rtc tick
#define FSID_HARD_FAULT_SIZE ((17+1+FSID_REC_EXTRA_BUF_LEN)*4+DEF_HARD_FAULT_DUMP_SP_LEN)
/*
17 for cpu reg,
1 for ICSR,
*/
#if(DEF_HARD_FAULT_LOG_DEBUG)
#define HF_DBG_LOG_PINOUT P9
#define HF_DBG_LOG log_printf
#define HF_DBG_LOG_baudrate 115200
#define HF_DBG_DUMMY_IO P27
#define HF_DBG_LOG_INIT {rom_uart_init(HF_DBG_LOG_baudrate,HF_DBG_LOG_PINOUT,HF_DBG_DUMMY_IO,NULL);}
#else
#define HF_DBG_LOG(...)
#define HF_DBG_LOG_INIT
#endif
// 这里声明了一些函数指针 trap_c_callback 和外部函数的声明,用于日志打印、获取系统计时器值、初始化串口等功能。
void (*trap_c_callback)(void);
extern void log_printf(const char* format, ...);
extern uint32_t rtc_get_counter(void);
extern uint32 osal_sys_tick;
extern int rom_uart_init(int baud, gpio_pin_e tx_pin, gpio_pin_e rx_pin, comm_cb_t cb);
#if defined ( __CC_ARM )
/*
这是硬件故障处理函数 _hard_fault 的实现部分。当系统发生硬件故障时,处理器会跳转到这个函数来处理。主要功能包括:
输出当前硬件故障时的寄存器状态、堆栈信息、系统状态等到调试日志中。
获取当前活动任务的信息,并记录到 buf 数组中,包括任务ID、任务函数指针、系统计时器值和实时时钟计数器值。
输出堆栈内容,以便后续分析硬件故障的具体原因。
根据宏定义判断是否需要记录硬件故障信息到文件系统中。
arg 指向堆栈中的数据。这些数据包含了硬件故障发生时的系统状态信息。
*/
void _hard_fault(uint32_t* arg)
{
uint32_t* stk = (uint32_t*)((uint32_t)arg);
uint8 task_cnt = *(uint8*)JUMP_FUNCTION(TASK_COUNT); //通过调用 JUMP_FUNCTION(TASK_COUNT) 获取任务数量
pTaskEventHandlerFn pFunc=NULL; // 用于存储当前活动任务的事件处理函数指针。
uint8_t* p_activeTaskID = (uint8_t*)0x1fff08b4;//activeTaskID 指向存储活动任务ID的地址
uint32_t buf[FSID_REC_EXTRA_BUF_LEN]; //存储硬件故障发生时的相关信息的数组。
HF_DBG_LOG_INIT; //日志初始化
// 打印寄存器和状态信息
HF_DBG_LOG("\n[Hard fault handler]\n");
HF_DBG_LOG("R0-R3 = 0x%08x 0x%08x 0x%08x 0x%08x\n", stk[9], stk[10], stk[11], stk[12]);
HF_DBG_LOG("R4-R7 = 0x%08x 0x%08x 0x%08x 0x%08x\n", stk[1], stk[2], stk[3], stk[4]);
HF_DBG_LOG("R8-R11 = 0x%08x 0x%08x 0x%08x 0x%08x\n", stk[5], stk[6], stk[7], stk[8]);
HF_DBG_LOG("R12,SP,LR,PC = 0x%08x 0x%08x 0x%08x 0x%08x\n", stk[13], stk[0], stk[14], stk[15]);
HF_DBG_LOG("PSR = 0x%08x ", stk[16]);
HF_DBG_LOG("ICSR = 0x%08x\n", *(volatile uint32_t*)0xE000ED04);
// 根据当前活动任务的ID,获取其对应的事件处理函数指针 pFunc。
if(p_activeTaskID[0]<task_cnt)
pFunc = ((pTaskEventHandlerFn*)(JUMP_FUNCTION(TASKS_ARRAY)))[p_activeTaskID[0]];
// 将当前活动任务ID、事件处理函数指针、系统计时器(systick)值以及实时时钟(RTC)计数器值记录到 buf 数组中,并输出到调试日志中。
buf[0]=p_activeTaskID[0];
buf[1]=(uint32_t)pFunc;
buf[2]=osal_sys_tick;
buf[3]=rtc_get_counter();
HF_DBG_LOG("[OSAL]idx %d Func 0x%08x systick %08x rtc %08x\n ",buf[0],buf[1],buf[2],buf[3]);
(void) buf;
// 这段代码用于输出堆栈内容。首先计算堆栈指针 sp,然后循环读取并打印堆栈中的数据。read_reg 函数用于读取堆栈中指定地址的值。
HF_DBG_LOG("-----------dump stack--------------\n");
uint32 sp = stk[0]&0x1ffffffc;
for(int i=0; i<DEF_HARD_FAULT_DUMP_SP_LEN; i=i+4)
{
if(sp+i>0x1ffffffc)
break;
if(0==(i&0x0f))
HF_DBG_LOG("\n[%08X]",sp+i);
HF_DBG_LOG("%08x ",read_reg(sp+i));
}
// 如果启用了文件系统记录功能,调用 _hard_fault_record_process 函数来记录硬件故障信息到文件系统中。
#if( DEF_HARD_FAULT_FS_ENABLE)
_hard_fault_record_process(stk,buf,FSID_REC_EXTRA_BUF_LEN);
#endif
// 如果注册了回调函数 trap_c_callback,则执行该函数。通常用于在处理完硬件故障后进行额外的处理或通知。
if (trap_c_callback)
{
trap_c_callback();
}
// 在处理完硬件故障后,进入无限循环,保持系统停在当前状态,避免继续执行其他代码。
while (1);
}
/*
这段汇编代码是硬件故障的入口点 hard_fault。它的作用是:
在硬件故障发生时,保存当前堆栈和寄存器状态,并调用 C 函数 _hard_fault 来处理具体的故障情况。
这段汇编代码确保在硬件故障发生时能够将当前的执行状态有效地传递给 _hard_fault 函数进行处理。
*/
// *INDENT-OFF*
__asm void hard_fault(void)
{
PRESERVE8
IMPORT _hard_fault
ldr r0, = 0x1FFF0800 /*store in global config 0x1fff0400 0x1fff0800*/
subs r0, r0, #72
mov r1, sp
str r1, [r0]
adds r0, #4
stmia r0!, {r4 - r7}
mov r4, r8
mov r5, r9
mov r6, r10
mov r7, r11
stmia r0!, {r4 - r7}
pop {r4 - r5} /* pop rom Hardfault stack*/
pop {r4 - r7} /* pop exception entry R0-R1*/
stmia r0!, {r4 - r7}
pop {r4 - r7}/* pop exception entry R12 LR PC xPSR*/
stmia r0!, {r4 - r7}
subs r0, r0, #68
ldr r1, = _hard_fault
ldr r2, = 0x1FFF1830 /*mov sp to rom initial_sp*/
mov sp, r2
bx r1
ALIGN 4
}
- main.c
#include "bus_dev.h"
#include "gpio.h"
#include "clock.h"
#include "timer.h"
#include "jump_function.h"
#include "pwrmgr.h"
#include "mcu.h"
#include "gpio.h"
#include "log.h"
#include "rf_phy_driver.h"
#include "flash.h"
#include "version.h"
// 总线设备操作、GPIO控制、时钟管理、定时器、跳转函数(可能是为了处理函数指针的跳转)、电源管理、MCU相关操作、日志输出、射频物理驱动、闪存操作和版本信息。
/*********************************************************************
LOCAL FUNCTION PROTOTYPES
*/
/*********************************************************************
EXTERNAL FUNCTIONS
*/
extern void init_config(void);
extern int app_main(void);
extern void hal_rom_boot_init(void);
/*********************************************************************
CONNECTION CONTEXT RELATE DEFINITION
*/
#define BLE_MAX_ALLOW_CONNECTION 1
#define BLE_MAX_ALLOW_PKT_PER_EVENT_TX 2
#define BLE_MAX_ALLOW_PKT_PER_EVENT_RX 2
#define BLE_PKT_VERSION BLE_PKT_VERSION_5_1 //BLE_PKT_VERSION_5_1 //BLE_PKT_VERSION_5_1
/* BLE_MAX_ALLOW_PER_CONNECTION
{
...
struct ll_pkt_desc *tx_conn_desc[MAX_LL_BUF_LEN]; // new Tx data buffer
struct ll_pkt_desc *rx_conn_desc[MAX_LL_BUF_LEN];
struct ll_pkt_desc *tx_not_ack_pkt;
struct ll_pkt_desc *tx_ntrm_pkts[MAX_LL_BUF_LEN];
...
}
tx_conn_desc[] + tx_ntrm_pkts[] --> BLE_MAX_ALLOW_PKT_PER_EVENT_TX * BLE_PKT_BUF_SIZE*2
rx_conn_desc[] --> BLE_MAX_ALLOW_PKT_PER_EVENT_RX * BLE_PKT_BUF_SIZE
tx_not_ack_pkt --> 1*BLE_PKT_BUF_SIZE
*/
// BLE连接的内存配置
#define BLE_PKT_BUF_SIZE (((BLE_PKT_VERSION == BLE_PKT_VERSION_5_1) ? 1 : 0) * BLE_PKT51_LEN \
+ ((BLE_PKT_VERSION == BLE_PKT_VERSION_4_0) ? 1 : 0) * BLE_PKT40_LEN \
+ (sizeof(struct ll_pkt_desc) - 2))
#define BLE_MAX_ALLOW_PER_CONNECTION ( (BLE_MAX_ALLOW_PKT_PER_EVENT_TX * BLE_PKT_BUF_SIZE*2) \
+(BLE_MAX_ALLOW_PKT_PER_EVENT_RX * BLE_PKT_BUF_SIZE) \
+ BLE_PKT_BUF_SIZE )
#define BLE_CONN_BUF_SIZE (BLE_MAX_ALLOW_CONNECTION * BLE_MAX_ALLOW_PER_CONNECTION)
// 内存对齐和定义
ALIGN4_U8 g_pConnectionBuffer[BLE_CONN_BUF_SIZE];
llConnState_t pConnContext[BLE_MAX_ALLOW_CONNECTION];
/*********************************************************************
CTE IQ SAMPLE BUF config
*/
//#define BLE_SUPPORT_CTE_IQ_SAMPLE TRUE
// 支持CTE IQ采样的内存配置
#ifdef BLE_SUPPORT_CTE_IQ_SAMPLE
uint16 g_llCteSampleI[LL_CTE_MAX_SUPP_LEN * LL_CTE_SUPP_LEN_UNIT];
uint16 g_llCteSampleQ[LL_CTE_MAX_SUPP_LEN * LL_CTE_SUPP_LEN_UNIT];
#endif
/*********************************************************************
OSAL LARGE HEAP CONFIG
*/
// OSAL大堆内存配置
#define LARGE_HEAP_SIZE (4*1024)
ALIGN4_U8 g_largeHeap[LARGE_HEAP_SIZE];
/*********************************************************************
GLOBAL VARIABLES
*/
volatile uint8 g_clk32K_config;
volatile sysclk_t g_spif_clk_config;
/*********************************************************************
EXTERNAL VARIABLES
*/
extern uint32_t __initial_sp;
static void hal_low_power_io_init(void)
{
//========= pull all io to gnd by default 初始化IO引脚配置,包括上拉、下拉和悬空配置
ioinit_cfg_t ioInit[]=
{
//TSOP6252 10 IO
{GPIO_P02, GPIO_FLOATING },/*SWD*/
{GPIO_P03, GPIO_FLOATING },/*SWD*/
{GPIO_P09, GPIO_PULL_UP },/*UART TX*/
{GPIO_P10, GPIO_PULL_UP },/*UART RX*/
{GPIO_P11, GPIO_PULL_DOWN },
{GPIO_P14, GPIO_PULL_DOWN },
{GPIO_P15, GPIO_PULL_DOWN },
{GPIO_P16, GPIO_FLOATING },
{GPIO_P18, GPIO_PULL_DOWN },
{GPIO_P20, GPIO_PULL_DOWN },
#if(SDK_VER_CHIP==__DEF_CHIP_QFN32__)
//6222 23 IO QFN32芯片的额外IO配置
{GPIO_P00, GPIO_PULL_DOWN },
{GPIO_P01, GPIO_PULL_DOWN },
{GPIO_P07, GPIO_PULL_DOWN },
{GPIO_P17, GPIO_FLOATING },/*32k xtal*/
{GPIO_P23, GPIO_PULL_DOWN },
{GPIO_P24, GPIO_PULL_DOWN },
{GPIO_P25, GPIO_PULL_DOWN },
{GPIO_P26, GPIO_PULL_DOWN },
{GPIO_P27, GPIO_PULL_DOWN },
{GPIO_P31, GPIO_PULL_DOWN },
{GPIO_P32, GPIO_PULL_DOWN },
{GPIO_P33, GPIO_PULL_DOWN },
{GPIO_P34, GPIO_PULL_DOWN },
#endif
};
// 依次配置每个IO引脚
for(uint8_t i=0; i<sizeof(ioInit)/sizeof(ioinit_cfg_t); i++)
hal_gpio_pull_set(ioInit[i].pin,ioInit[i].type);
// 配置DCDC和LDO电源
DCDC_CONFIG_SETTING(0x0a);
DCDC_REF_CLK_SETTING(1);
DIG_LDO_CURRENT_SETTING(0x01);
//hal_pwrmgr_RAM_retention(RET_SRAM0|RET_SRAM1|RET_SRAM2); 配置RAM保持
hal_pwrmgr_RAM_retention(RET_SRAM0);
hal_pwrmgr_RAM_retention_set();
hal_pwrmgr_LowCurrentLdo_enable();
}
static void ble_mem_init_config(void)
{ // 设置OSAL的大堆内存
osal_mem_set_heap((osalMemHdr_t*)g_largeHeap, LARGE_HEAP_SIZE);
// 初始化连接上下文和CTE IQ采样缓冲区(如果支持)
LL_InitConnectContext(pConnContext,
g_pConnectionBuffer,
BLE_MAX_ALLOW_CONNECTION,
BLE_MAX_ALLOW_PKT_PER_EVENT_TX,
BLE_MAX_ALLOW_PKT_PER_EVENT_RX,
BLE_PKT_VERSION);
#ifdef BLE_SUPPORT_CTE_IQ_SAMPLE
// 如果支持CTE IQ采样,还会初始化相应的IQ采样缓冲区。
LL_EXT_Init_IQ_pBuff(g_llCteSampleI,g_llCteSampleQ);
#endif
}
static void hal_rfphy_init(void)
{
//============config the txPower // 配置射频物理层参数
g_rfPhyTxPower = RF_PHY_TX_POWER_0DBM ;
//============config BLE_PHY TYPE
g_rfPhyPktFmt = PKT_FMT_BLE1M;
//============config RF Frequency Offset
g_rfPhyFreqOffSet =RF_PHY_FREQ_FOFF_00KHZ;
//============config xtal 16M cap 配置16M晶振的电容和电流
XTAL16M_CAP_SETTING(0x09);
XTAL16M_CURRENT_SETTING(0x03);
// 初始化RC32K时钟跟踪和ROM引导初始化
hal_rc32k_clk_tracking_init();
hal_rom_boot_init();
// 设置中断优先级
NVIC_SetPriority((IRQn_Type)BB_IRQn, IRQ_PRIO_REALTIME);
NVIC_SetPriority((IRQn_Type)TIM1_IRQn, IRQ_PRIO_HIGH); //ll_EVT
NVIC_SetPriority((IRQn_Type)TIM2_IRQn, IRQ_PRIO_HIGH); //OSAL_TICK
NVIC_SetPriority((IRQn_Type)TIM4_IRQn, IRQ_PRIO_HIGH); //LL_EXA_ADV
//ble memory init and config 初始化BLE内存和配置
ble_mem_init_config();
}
static void hal_init(void)
{
// 初始化低功耗IO
hal_low_power_io_init();
// 初始化时钟
clk_init(g_system_clk); //system init
// 配置RTC时钟
hal_rtc_clock_config((CLK32K_e)g_clk32K_config);
// 初始化电源管理
hal_pwrmgr_init();
// 配置Flash SPI缓存
xflash_Ctx_t cfg =
{
.rd_instr = XFRD_FCMD_READ_DUAL
};
hal_spif_cache_init(cfg);
// 初始化日志输出
LOG_INIT();
// 初始化GPIO
hal_gpio_init();
}
// 静态函数声明,它们将在后面的代码中定义,用于初始化不同的硬件和系统配置。
#define _BUILD_FOR_DTM_IN_APP_ 0
/
int main(void)
{
g_system_clk = SYS_CLK_XTAL_16M;//SYS_CLK_XTAL_16M;//SYS_CLK_DLL_64M;
g_clk32K_config = CLK_32K_RCOSC;//CLK_32K_XTAL;//CLK_32K_XTAL,CLK_32K_RCOSC
#if(FLASH_PROTECT_FEATURE == 1)
hal_flash_lock();
#endif
drv_irq_init(); //初始化中断
init_config(); //初始化配置
hal_rfphy_init(); // 初始化射频物理层
hal_init(); //初始化HAL
#if(_BUILD_FOR_DTM_IN_APP_==1)
rf_phy_direct_test(); // 如果是为DTM构建的应用,执行射频物理层的直接测试
#endif
// 打印SDK版本信息和一些系统参数
LOG("SDK Version ID %08x \n",SDK_VER_RELEASE_ID);
LOG("rfClk %d rcClk %d sysClk %d tpCap[%02x %02x]\n",g_rfPhyClkSel,g_clk32K_config,g_system_clk,g_rfPhyTpCal0,g_rfPhyTpCal1);
LOG("sizeof(struct ll_pkt_desc) = %d, buf size = %d\n", sizeof(struct ll_pkt_desc), BLE_CONN_BUF_SIZE);
LOG("sizeof(g_pConnectionBuffer) = %d, sizeof(pConnContext) = %d, sizeof(largeHeap)=%d \n",\
sizeof(g_pConnectionBuffer), sizeof(pConnContext),sizeof(g_largeHeap));
app_main(); // 执行应用程序的主函数
}
/ end ///
烧录
在keil将代码编译之后,然后使用烧录工具对pb03f进行烧录