| name | pb03f |
| description | PHY62XX (PB03F) BLE SoC SDK 3.1.5 开发专家知识库,涵盖工程结构、驱动 API(GPIO/UART/I2C/SPI/ADC/Timer/PWM/DMA/Flash/Watchdog)、BLE 协议栈、OSAL 任务模型、低功耗管理、BLE Mesh、OTA 等核心开发要点。触发条件:项目或对话涉及 PB03F、PHY6222、PHY6252、PHY62XX、奉天系列 BLE SoC,或用户请求该平台的外设驱动开发、BLE 应用开发、OSAL 任务编写、低功耗配置。 |
触发条件
以下任一情况自动加载本技能:
- 项目路径或文件名包含
phy62、pb03、phyplus
- 用户提及 PB03F、PHY6222、PHY6252、PHY62XX、奉天电子 BLE 芯片
- 请求编写 PHY62XX 平台代码(GPIO/UART/I2C/SPI/ADC/Timer/PWM 驱动、BLE 从机/主机/Mesh 应用)
- 咨询 OSAL 任务系统、BLE Profile 配置、低功耗/睡眠模式、OTA 升级
- 调试 PHY62XX 硬件问题或 Keil MDK 工程配置
PB03F / PHY62XX SDK 开发技能库
一、芯片与SDK概述
- 芯片:PHY6222 / PHY6252(PB03F封装)
- 内核:ARM Cortex-M0
- SDK版本:PHY62XX_SDK_3.1.5
- 开发工具:Keil MDK(主要)/ GCC(部分示例支持)
- 烧录方式:SWD(P02/P03)或 XIP Flash
芯片集成 BLE 5.1 射频,内置 Flash(XIP 执行),SRAM 分三块:
- SRAM0:32KB,地址
0x1fff0000~0x1fff7fff
- SRAM1:16KB,地址
0x1fff8000~0x1fffbfff
- SRAM2:16KB,地址
0x1fffc000~0x1fffffff
二、工程目录结构
SDK根目录/
├── components/
│ ├── arch/ # 架构相关(启动、中断向量)
│ ├── ble/ # BLE协议栈头文件(controller/hci/host/include)
│ ├── driver/ # 片上外设驱动
│ ├── gcc/ # GCC链接脚本等
│ ├── inc/ # 公共头文件(types.h, bus_dev.h等)
│ ├── keil/ # Keil分散加载文件
│ ├── libraries/ # 工具库(fs, crypto, cli, crc16等)
│ ├── osal/ # 操作系统抽象层
│ └── profiles/ # BLE Profile(角色、服务、OTA等)
├── example/
│ ├── peripheral/ # 纯外设Demo(GPIO/UART/SPI/ADC/Timer等)
│ ├── ble_peripheral/# BLE从设备Demo(simpleBLE/HID/pwmLight等)
│ ├── ble_central/ # BLE主设备Demo
│ ├── ble_multi/ # 多角色Demo(主从并存,最多5连接)
│ ├── ble_mesh/ # BLE Mesh Demo(light/switch/gateway/lpn等)
│ ├── OTA/ # OTA升级Demo
│ └── PhyPlusPhy/ # 2.4G私有协议Demo
├── lib/ # 预编译库(rf.lib/ble_host.lib/mesh.lib等)
└── misc/ # ROM符号表、jump_table等
三、驱动层 API(components/driver/)
3.1 GPIO(gpio/gpio.h)
PIN枚举:gpio_pin_e,命名规则 GPIO_P00GPIO_P34,别名 P0P34
hal_gpio_init();
hal_gpio_pin_init(P9, GPIO_OUTPUT);
hal_gpio_pin_init(P10, GPIO_INPUT);
hal_gpio_write(P9, 1);
hal_gpio_write(P9, 0);
bool val = hal_gpio_read(P10);
hal_gpio_pull_set(P10, GPIO_PULL_UP);
hal_gpio_fmux_set(P9, FMUX_UART0_TX);
hal_gpio_fmux_set(P10, FMUX_UART0_RX);
hal_gpio_fmux(P9, Bit_ENABLE);
typedef void (*gpioin_Hdl_t)(gpio_pin_e pin, gpio_polarity_e type);
hal_gpioin_register(P7, posedge_cb, negedge_cb);
hal_gpioin_enable(P7);
hal_gpioin_disable(P7);
hal_gpioin_unregister(P7);
hal_gpio_cfg_analog_io(P11, Bit_ENABLE);
3.2 UART(uart/uart.h)
uart_Cfg_t cfg = {
.tx_pin = P9,
.rx_pin = P10,
.rts_pin = GPIO_DUMMY,
.cts_pin = GPIO_DUMMY,
.baudrate = 115200,
.use_fifo = TRUE,
.hw_fwctrl = FALSE,
.use_tx_buf = FALSE,
.parity = FALSE,
.evt_handler = uart_rx_cb,
};
hal_uart_init(cfg, UART0);
hal_uart_send_byte(UART0, 0xAB);
hal_uart_send_buff(UART0, buf, len);
3.3 I2C(i2c/i2c.h)
#include "i2c.h"
hal_i2c_init(I2C_0, I2C_CLOCK_400K, P2, P3, i2c_evt_cb);
hal_i2c_tx_start(I2C_0, slave_addr, buf, len, I2C_STOP);
hal_i2c_rx_start(I2C_0, slave_addr, buf, len, I2C_STOP);
hal_i2c_deinit(I2C_0);
3.4 SPI(spi/spi.h)
#include "spi.h"
spi_Cfg_t spi_cfg = {
.sclk_pin = P14,
.ssn_pin = P15,
.MOSI = P16,
.MISO = P17,
.baudrate = 4000000,
.spi_tmod = SPI_TRXD,
.spi_scph = SPI_SCPH_1EDGE,
.spi_scpol= SPI_SCPOL_HIGH,
.spi_dfs = SPI_8BIT,
.force_cs_ctrl = FORCE_CS_IDLE,
.evt_handler = spi_evt_cb,
};
hal_spi_init(SPI0, spi_cfg);
hal_spi_send_and_recv(SPI0, tx_buf, tx_len, rx_buf, rx_len);
3.5 ADC(adc/adc.h)
hal_adc_init();
adc_Cfg_t adc_cfg = {
.channel = ADC_CH0,
.is_continue_mode = FALSE,
.is_differential_mode = 0,
.is_high_resolution = 1,
};
hal_adc_config_channel(adc_cfg, adc_data_cb);
hal_adc_clock_config(HAL_ADC_CLOCK_320K);
hal_adc_start(POLLING_MODE);
hal_adc_stop();
hal_adc_deinit();
ADC通道与引脚对应:
| 通道 | 引脚 |
|---|
| ADC_CH0 (单端) | P11 |
| ADC_CH1 (单端) | P23 |
| ADC_CH2 (单端) | P24 |
| ADC_CH3 (单端) | P14 |
| ADC_CH4 (单端) | P15 |
| ADC_CH9 (单端) | P20 |
| ADC_CH1DIFF | P23(+)/P11(-) |
| ADC_CH2DIFF | P14(+)/P24(-) |
| ADC_CH3DIFF | P20(+)/P15(-) |
3.6 Timer(timer/timer.h)
#include "timer.h"
hal_timer_init(AP_TIM3);
hal_timer_set(AP_TIM3, 1000);
hal_timer_start(AP_TIM3);
hal_timer_stop(AP_TIM3);
hal_timer_deinit(AP_TIM3);
3.7 PWM(pwm/pwm.h)
#include "pwm.h"
hal_pwm_init(PWM_CH0, 1000 , 50 , P11);
hal_pwm_start(PWM_CH0);
hal_pwm_stop(PWM_CH0);
hal_pwm_set_param(PWM_CH0, 2000, 80);
3.8 DMA(dma/dma.h)
#include "dma.h"
hal_dma_init();
3.9 Flash(flash/flash.h)
#include "flash.h"
hal_flash_write(addr, buf, len);
hal_flash_read(addr, buf, len);
hal_flash_erase_sector(addr);
hal_flash_erase_block64(addr);
uint8_t mac[6];
hal_flash_get_mac_address(mac);
hal_flash_enable_lock(MAIN_INIT);
3.10 Watchdog(watchdog/watchdog.h)
#include "watchdog.h"
watchdog_config(WDG_2S);
hal_watchdog_feed();
3.11 日志输出(log/log.h)
#include "log.h"
LOG_INIT();
LOG("value=%d\n", val);
LOG_DUMP_BYTE(buf, len);
3.12 电源管理(pwrmgr/pwrmgr.h)
#include "pwrmgr.h"
hal_pwrmgr_init();
hal_pwrmgr_lock(MOD_USR0);
hal_pwrmgr_unlock(MOD_USR0);
hal_pwrmgr_register(MOD_USR0, sleep_cb, wakeup_cb);
hal_pwrmgr_RAM_retention(RET_SRAM0 | RET_SRAM1);
hal_pwrmgr_RAM_retention_set();
hal_pwrmgr_LowCurrentLdo_enable();
pwroff_cfg_t wakeup_pin = { .pin = P7, .type = POL_RISING, .on_time = 10 };
hal_pwrmgr_poweroff(&wakeup_pin, 1);
hal_pwrmgr_enter_standby(&wakeup_pin, 1);
睡眠模式配置(main.c 中):
四、OSAL 任务系统
4.1 初始化流程(固定模式)
int app_main(void) {
osal_init_system();
osal_pwrmgr_device(PWRMGR_BATTERY);
osal_start_system();
return 0;
}
const pTaskEventHandlerFn tasksArr[] = {
LL_ProcessEvent,
Hci_ProcessEvent,
GAPRole_ProcessEvent,
GAPBondMgr_ProcessEvent,
GAP_ProcessEvent,
SM_ProcessEvent,
GATT_ProcessEvent,
ATT_ProcessEvent,
L2CAP_ProcessEvent,
GATTServApp_ProcessEvent,
DevInfo_ProcessEvent,
SimpleProfile_ProcessEvent,
Batt_ProcessEvent,
OSAL_user_task_ProcessEvent,
};
4.2 用户任务模板
uint8 MyTask_TaskID;
void MyTask_Init(uint8 task_id);
uint16 MyTask_ProcessEvent(uint8 task_id, uint16 events);
void MyTask_Init(uint8 task_id) {
MyTask_TaskID = task_id;
osal_start_timerEx(MyTask_TaskID, MY_PERIODIC_EVT, 1000);
}
uint16 MyTask_ProcessEvent(uint8 task_id, uint16 events) {
if (events & MY_PERIODIC_EVT) {
osal_start_timerEx(MyTask_TaskID, MY_PERIODIC_EVT, 1000);
return (events ^ MY_PERIODIC_EVT);
}
return 0;
}
4.3 OSAL 常用API
osal_start_timerEx(task_id, event, timeout_ms);
osal_stop_timerEx(task_id, event);
osal_get_timeoutEx(task_id, event);
uint8* p = osal_mem_alloc(size);
osal_mem_free(p);
osal_event_hdr_t* msg = (osal_event_hdr_t*)osal_msg_allocate(sizeof(osal_event_hdr_t));
msg->event = MY_MSG_EVT;
osal_msg_send(task_id, (uint8*)msg);
uint8* msg = osal_msg_receive(task_id);
osal_msg_deallocate(msg);
osal_set_event(task_id, event_flag);
五、BLE 协议栈
5.1 main.c 关键配置
#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
#define LARGE_HEAP_SIZE (3*1024)
g_system_clk = SYS_CLK_XTAL_16M;
g_clk32K_config = CLK_32K_RCOSC;
g_rfPhyTxPower = RF_PHY_TX_POWER_N2DBM;
ll_patch_slave();
ll_patch_advscan();
ll_patch_sleep();
ll_patch_no_sleep();
5.2 BLE 角色 Profile
从设备角色(profiles/Roles/peripheral.h):
#include "peripheral.h"
static gapRolesCBs_t myApp_roleCBs = {
.pfnStateChange = peripheralStateNotificationCB,
.pfnRssiRead = NULL,
.pfnParamUpdate = NULL,
};
GAPRole_StartDevice(&myApp_roleCBs);
主设备角色(profiles/Roles/central.h):
#include "central.h"
GAPCentralRole_StartDevice(&myApp_roleCBs);
GAPCentralRole_StartDiscovery(DEFAULT_DISCOVERY_MODE, TRUE, FALSE);
GAPCentralRole_EstablishLink(FALSE, FALSE, peer_addrType, peer_addr);
多角色(profiles/multiRole/multi.h):
#include "multi.h"
GAPMultiRole_StartDevice(&myApp_roleCBs);
5.3 GATT 服务注册
#include "simpleProfile.h"
SimpleProfile_AddService(GATT_ALL_SERVICES);
SimpleProfile_RegisterAppCBs(&simpleBLEPeripheral_SimpleProfileCBs);
GATTServApp_ProcessCharCfg(simpleProfileCharCfgTable, &charValue,
FALSE, simpleProfileAttrTbl,
GATT_NUM_ATTRS(simpleProfileAttrTbl),
INVALID_TASK_ID);
5.4 OTA
#include "ota_service.h"
OTA_AddService();
六、BLE Mesh
七、文件系统(FS)
#include "fs.h"
fs_init(FLASH_UCDS_ADDR_BASE, 0x1000 );
fs_write(FS_KEY_ID, data, len);
fs_read(FS_KEY_ID, buf, len);
fs_remove(FS_KEY_ID);
八、加密库
#include "crc16.h"
uint16_t crc = crc16(data, len);
九、新建工程流程(Keil)
- 复制
example/ble_peripheral/simpleBlePeripheral/ 为模板
- 修改
scatter_load.sct 中的内存分布(XIP Flash 段 / SRAM 段)
main.c 中调整:
BLE_MAX_ALLOW_CONNECTION(连接数)
LARGE_HEAP_SIZE(堆大小)
g_system_clk(系统时钟)
g_clk32K_config(32K时钟源)
g_rfPhyTxPower(发射功率)
OSAL_xxx.c 中注册任务表(tasksArr[])
- 实现用户任务
xxx_Init() 和 xxx_ProcessEvent()
- Keil 工程选项:
- Device:ARMCM0
- 添加必要 lib:
lib/ble_host.lib、lib/rf.lib(或 rf_light.lib)
- 头文件路径包含:
components/inc、components/osal/include、components/ble/include、components/driver/xxx
- 宏定义:
PHYPLUS_GCC(GCC时)或无(Keil时)
十、调试
- SWD调试:使用 Keil 连接 P02(SWDCLK)/P03(SWDIO),加载
ram.ini(RAM调试)或 ram_xip.ini(XIP调试)
- 日志:UART0 (P09=TX, P10=RX), 115200bps,
LOG("...")
- ROM符号:
misc/bb_rom_sym_m0.gdbsym 用于GDB调试时加载ROM函数符号
- DTM测试:P20=HIGH 时进入直接测试模式(
rf_phy_direct_test())
- hardfault:
misc/jump_table.c 中有 _hard_fault 处理(输出PC/LR等)
十一、预编译库说明
| 库文件 | 用途 |
|---|
rf.lib / libphy6222_rf.a | BLE射频控制器(LL层),完整功能 |
rf_light.lib | 精简射频库,从设备省SRAM |
rf_mst.lib | 主设备/Mesh专用射频库 |
ble_host.lib / libphy6222_host.a | BLE Host层(HCI/L2CAP/ATT/GATT/SM/GAP) |
mesh.lib | BLE Mesh协议栈(EtherMind) |
phy_font.lib | 字库(UI相关) |
libphy6222_sec_boot.a | 安全启动(SLB) |
十三、附加资料索引
以下文件位于 .augment/skills/pb03f/docs/ 目录下,需要查阅时通过 view 工具读取完整内容。
| 文件 | 主题 | 关键内容速查 |
|---|
docs/PHY6222 BLE SoC 数据手册.md | 芯片数据手册 | QFN32/QFN24引脚定义、内存地址映射、电源模式电流、时钟源、ADC/RF/外设规格、封装订购型号、PCB布局建议 |
docs/PHY622X ADC Application Note.md | ADC / Voice | ADC引脚(P11/P14/P15/P18/P20/P23/P24/P25)、bypass vs attenuation模式、量程(00.8V/03.2V)、衰减系数校准、Voice AMIC/DMIC配置、adc_Cfg_t 结构体、hal_voice_config() |
docs/PHY622X GPIO Application Note.md | GPIO / FULLMUX / KSCAN | 特殊IO限制(P16/P17/P1/SWD)、GPIO模式/retention/上下拉、中断唤醒配置、FULLMUX映射表(FMUX_UART0_TX=4等37个枚举)、KSCAN矩阵按键mk_in/mk_out与GPIO对应关系、完整API示例代码 |
docs/PHY622X Peripheral Application Note.md | 外设驱动概述 | WATCHDOG(喂狗周期2256s)、TIMER(用户可用TIM3TIM6,时钟4MHz)、PWM(6路,16MHz源,UP/UP-DOWN模式占空比公式)、UART(2路,波特率计算公式,TX/RX FIFO=16B)、SPI(2路,FIFO=8,CPOL/CPHA)、I2C(2路,需外部上拉)、KSCAN(11行12列) |
docs/PHY622X_PWR_MGR应用指南.md | 电源管理 | 4种功耗模式(正常/CPU休眠/深度休眠/standby/关机)、PWR_MGR API(hal_pwrmgr_register/lock/unlock/RAM_retention/poweroff/enter_standby)、MODULE_e枚举(MOD_USR0~8供应用使用)、功耗评估模型与计算公式、上电启动时间(冷启91ms/唤醒3.4ms) |
docs/PHY622X_Security_Boot_User_Guide.md | 安全启动 | Efuse 4块(BLOCK0=ROM安全启动key,BLOCK1=OTA安全启动key)、efuse只能写一次且需奇校验、g_sec_key/g_ota_sec_key通过PhyPlusKit生成、ROM Security Boot流程、Flash地址映射(No OTA / Support OTA两种布局) |
docs/PHY62XX BSP_Button Application Note.md | 按键中间件 | BSP_Button支持GPIO/KSCAN/混合三种硬件、按键类型(按下/释放/长按开始/长按保持)、组合按键配置、宏定义BSP_BTN_HARDWARE_CONFIG/BSP_SINGLE_BTN_NUM/BSP_COMBINE_BTN_NUM、hal_gpio_btn_init()/hal_kscan_btn_check()完整示例 |
docs/PHY62XX MESH 开发指南.md | BLE Mesh开发 | EtherMind协议栈层次(7层)、工程目录结构、lib库说明(mesh_core/mesh_models/utils)、Model定义宏(USE_HSL/USE_CTL/USE_VENDORMODEL)、Mesh初始化完整流程(appl_mesh_sample)、Provision接口、Vendor Model/Generic OnOff回调实现示例、relay/proxy/friend开关API |
十二、常见宏定义
HOST_CONFIG
CFG_SLEEP_MODE
SDK_VER_CHIP
FLASH_PROTECT_FEATURE
CFG_HCLK_DYNAMIC_CHANGE