# BabyOS_Example **Repository Path**: notrynohigh/BabyOS_Example ## Basic Information - **Project Name**: BabyOS_Example - **Description**: 为BabyOS增加使用例子,请根据需要切换至对应分支 BabyOS作为子模块,因此克隆需要依次运行以下指令: ①git clone https://gitee.com/notrynohigh/BabyOS_Example.git ②git submodule init ③git submodule update - **Primary Language**: C - **License**: MIT - **Default Branch**: BearPi - **Homepage**: https://gitee.com/notrynohigh/BabyOS - **GVP Project**: No ## Statistics - **Stars**: 77 - **Forks**: 47 - **Created**: 2020-03-07 - **Last Updated**: 2025-06-06 ## Categories & Tags **Categories**: os **Tags**: None ## README # 基于BearPi玩转BabyOS V0.0.1 BabyOS V8.2.3 notrynohigh@outlook.com ***TO: 单片机入门者 or 开源爱好者*** https://gitee.com/notrynohigh/BabyOS https://gitee.com/notrynohigh/BabyOS_Example/tree/BearPi/
[TOC]
## 软硬件平台 **BearPi** ![2119fd4ba4b5cc4a](https://gitee.com/notrynohigh/BabyOS_Example/raw/BearPi/Doc/bearpi.jpg) | 序号 | 外设 | 接口 | 备注 | | ---- | ------------------ | ------ | --------- | | 1 | 屏(ST7789) | SPI2 | | | 2 | SPIFLASH(W25Q64) | QSPI | | | 3 | 按键(K1 K2) | GPIO | PB2 / PB3 | | 4 | WIFI(ESP12F) | LPUART | | | 5 | TF卡 | SDIO | | BearPi配的ESP12F模组,如果出厂固件不支持MQTT,可以更新如下固件: https://docs.ai-thinker.com/固件汇总 MQTT透传AT固件 (固件号:1112) **BabyOS** 仓库地址:https://gitee.com/notrynohigh/BabyOS 建议使用master分支代码。 如果是开源爱好者,有意向BabyOS仓库提交代码,则使用dev分支代码。 **BabyOS使用手册** https://gitee.com/notrynohigh/BabyOS/blob/master/doc/ **STM32CUBE MX** 软件下载地址:https://www.st.com/zh/development-tools/stm32cubemx.html **STM32L41XX参考手册** https://www.st.com/resource/en/reference_manual/rm0394-stm32l41xxx42xxx43xxx44xxx45xxx46xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf
## 创建基础工程 *具体代码参考 /Examples/template/* 1、使用STM32CUBE MX软件进行配置生成基础工程 stm32cubemx的工程文件在Board 目录 ![stm32cubemx](https://gitee.com/notrynohigh/BabyOS_Example/raw/BearPi/Doc/stm32cubemx.png) 2、加入BabyOS的代码 | 路径 | 部分/全部 | 备注 | | -------------- | ------------ | ------------------------------------------------------------ | | bos/algorithm | 根据需要添加 | *暂时不添加其中文件* | | bos/core | 全部添加 | *全部添加* | | bos/drivers | 根据需要添加 | *暂时不添加其中文件* | | bos/hal | 全部添加 | *全部添加* | | bos/mcu | 根据需要添加 | *添加bos/mcu/st/stm32l41x/路径代码* | | bos/modules | 全部添加 | *全部添加* | | bos/thirdparty | 根据需要添加 | *暂时不添加其中文件* | | bos/utils | 全部添加 | *全部添加* | | bos/_config | | *b_config.h 全局 配置文件
b_device_list.h 注册设备的文件
b_hal_if.h 驱动接口文件* | 编译器添加两个路径即可: `bos/` `_config/` 如果配置文件拷贝到其他路径了,则添加相应路径即可。 3、调用BabyOS必要函数 包含头文件 `b_os.h` ①滴答定时器中断服务函数调用 `bHalIncSysTick();` ```C // stm32l4xx_it.c #include "b_os.h" void SysTick_Handler(void) { /* USER CODE BEGIN SysTick_IRQn 0 */ /* USER CODE END SysTick_IRQn 0 */ HAL_IncTick(); /* USER CODE BEGIN SysTick_IRQn 1 */ bHalIncSysTick(); /* USER CODE END SysTick_IRQn 1 */ } ``` ②调用`bInit(); bExec();` ```C //main.c #include "b_os.h" int main() { ... bInit(); while(1) { bExec(); } } ```
## 独立按键 F1 F2 *具体代码参考 /Examples/key/* ![key_sch](https://gitee.com/notrynohigh/BabyOS_Example/raw/BearPi/Doc/key_sch.png) 根据原理图,需要了解的信息:两个独立按键,按下后,电平为低。 1、添加驱动文件 将 `b_drv_key.c` 添加至工程。 2、增加第三方代码flexible_button 由于按键功能模块的实现依赖于第三方开源代码,则将 `flexible_button.c` 添加至工程。 在配置文件`b_config.h`中使能flexible_button 3、增加按键的硬件接口 ```c //b_hal_if.h ... #define HAL_KEY_IF \ {B_HAL_GPIOB, B_HAL_PIN2, 0}, {B_HAL_GPIOB, B_HAL_PIN3, 0} ... ``` 4、注册设备 ```c //b_device_list.h ... B_DEVICE_REG(bKEYF1, B_DRIVER_KEY, "KEY-F1") B_DEVICE_REG(bKEYF2, B_DRIVER_KEY, "KEY-F2") ... ``` 5、编写例子 ① 按键F1单击则打印 hello BabyOS ② 按键F2单击则打印 hello BearPi ③ 按键F2双击则打印hello BabyOS BearPi ```C //main.c static void _KeyEventHandler(uint32_t dev_no, uint8_t sub_id, uint16_t event, uint8_t param) { if(dev_no == bKEYF1) { b_log("hello babyos \r\n"); } else { if(event == BTN_EVENT_CLICK) { b_log("hello BearPi\r\n"); } else { b_log("hello babyos BearPi\r\n"); } } } int main() { ... /* USER CODE BEGIN 2 */ bInit(); /* USER CODE END 2 */ bBUTTON_ADD_KEY(bKEYF1, BTN_EVENT_CLICK, _KeyEventHandler); bBUTTON_ADD_KEY(bKEYF2, BTN_EVENT_CLICK | BTN_EVENT_DOUBLE_CLICK, _KeyEventHandler); /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { bExec(); } } ``` 结果: ![key_result](https://gitee.com/notrynohigh/BabyOS_Example/raw/BearPi/Doc/key_result.png)
## TFT彩屏 *具体代码参考 /Examples/tft/* ![tft_sch](https://gitee.com/notrynohigh/BabyOS_Example/raw/BearPi/Doc/tft_sch.png) 从原理图需要获取的信息是:TFT彩屏的硬件接口是SPI 1、添加驱动文件 将 `b_drv_st7789.c` 添加至工程。 2、将gui文件添加至工程 BabyOS里面gui软件模块依赖于第三方开源代码,将 `ugui.c` 添加至工程。 `b_config.h`文件中配置使能UGUI。 3、添加硬件接口 ```C //b_hal_if.h #define HAL_ST7789_IF \ { \ .if_type = 2, \ ._if._spi._spi = \ { \ .is_simulation = 0, \ .cs = {B_HAL_GPIOC, B_HAL_PIN13}, \ ._if.spi = B_HAL_SPI_2, \ }, \ ._if._spi.rs = {B_HAL_GPIOC, B_HAL_PIN6}, \ } ``` 4、注册设备 ```C //b_device_list.h B_DEVICE_REG(bTFT, B_DRIVER_ST7789, "tft") ``` 5、编写例子 ①每5s产生随机坐标,显示“BabyOS BearPi” ```C //main.c static void _TestTFT() { static uint32_t t = 0; uint16_t x = 0, y = 0; srand(t++); x = rand() % (240 - 120); srand(t++); y = rand() % (320 - 16); b_log("x: %d y: %d\r\n", x, y); UG_PutString(x, y, "BabyOS BearPi"); } int main() { ... bInit(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ bGUI_ADD_DEVICE(bTFT, NULL, 240, 320, 0); UG_FillScreen(C_RED); while (1) { bExec(); BOS_PERIODIC_TASK(_TestTFT, 5000); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } } ``` 结果: ![tft_result](https://gitee.com/notrynohigh/BabyOS_Example/raw/BearPi/Doc/tft_result.png)![tft_result2](https://gitee.com/notrynohigh/BabyOS_Example/raw/BearPi/Doc/tft_result2.jpg)
## SPIFLASH *具体代码参考 /Examples/spiflash/* ![spiflash_sch](https://gitee.com/notrynohigh/BabyOS_Example/raw/BearPi/Doc/spiflash_sch.png) 从原理图需要获取的信息是:SPIFLASH存储器的接口QSPI 1、添加驱动文件 将 `b_drv_spiflash.c` 添加至工程。 spiflash依赖于第三方开源代码sfud,将BabyOS/bos/drivers/sfud路径的代码添加进工程。 2、添加硬件接口 ```C //b_hal_if.h #define HAL_SPIFLASH_IF \ { \ .is_spi = 0, ._if._qspi = B_HAL_QSPI_1, \ } ``` 3、注册设备 ```C //b_device_list.h B_DEVICE_REG(bSPIFLASH, B_DRIVER_SPIFLASH, "spiflash") ``` 4、编写例子 ①记录开机次数 ```C //main.c static void _TestSpiflash() { int fd = -1; uint32_t boot[2]; fd = bOpen(bSPIFLASH, BCORE_FLAG_RW); if(fd < 0) { return; } bLseek(fd, 0); bRead(fd, (uint8_t *)boot, sizeof(boot)); if(boot[0] != 0x12345678) { boot[0] = 0x12345678; boot[1] = 1; } else { boot[1] += 1; } b_log("boot: %d\r\n", boot[1]); bFlashErase_t param = {0, 1}; bCtl(fd, bCMD_ERASE_SECTOR, ¶m); bLseek(fd, 0); bWrite(fd, (uint8_t *)boot, sizeof(boot)); bClose(fd); } int main() { ... bInit(); _TestSpiflash(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { bExec(); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } } ``` 结果: spiflash_result
## TF-Card *具体代码参考 /Examples/tfcard/* ![tf_sch](https://gitee.com/notrynohigh/BabyOS_Example/raw/BearPi/Doc/tf_sch.png) 从原理图需要获取的信息是:TF-Card使用是SDIO 1、添加驱动文件 将 `b_drv_sd.c` 添加至工程。 `b_config.h` 文件配置使用FatFS,将第三方开源代码FatFS加入工程 2、添加硬件接口 ```C //b_hal_if.h #define HAL_SD_IF \ { \ .is_spi = 0, ._if._sdio = B_HAL_SDIO_1, \ } ``` 3、注册设备 ```C //b_device_list.h B_DEVICE_REG(bSD, B_DRIVER_SD, "tf-card") ``` 4、编写例子 ①使用文件记录开机次数 ```C //main.c int main() { ... bInit(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ bFS_Init(); bFS_Test(); while (1) { bExec(); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } } ``` 结果: ![tf_result](https://gitee.com/notrynohigh/BabyOS_Example/raw/BearPi/Doc/tf_result.png)
## WiFi-MQTT *具体代码参考 /Examples/wifi/* wifi_sch 从原理图需要获取的信息是:WiFi使用的是LPUART1 1、添加驱动文件 将 `b_drv_esp12f.c` 添加至工程。 需要增加1个按键,让模组进入配网模式,将`b_drv_key.c`添加至工程。 `b_config.h` 文件配置使能b_mod_wifi 例子中涉及状态的切换。`b_config.h` 配置使能状态机功能模块。 2、添加硬件接口 ```C //b_hal_if.h #define HAL_ESP12F_IF B_HAL_LPUART_1 ``` 3、注册设备 ```C //b_device_list.h B_DEVICE_REG(bESP12F, B_DRIVER_ESP12F, "WiFi") B_DEVICE_REG(bKEYF1, B_DRIVER_KEY, "KEY-F1") ``` 4、编写例子 ①离线时周期性ping www.baidu.com ②在线时订阅主题 baby 每1分钟往主题os发布一条消息 ③长按按键F1进入和退出配网。 配网格式:ssid:notrynohigh passwd:11223344 ssid: notrynohigh passwd:11223344 ```C //main.c //按键事件回调,长按F1之后触发配网事件 static void _ButtonEventHandler(uint32_t dev_no, uint8_t sub_id, uint16_t event, uint8_t param) { if(dev_no == bKEYF1) { if(event == BTN_EVENT_LONG) { bStateInvokeEvent(EVENT_CFG_NET, NULL); } } } //LPUART1接收数据喂给b_util_uart void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart == &hlpuart1) { bUtilUartRxHandler2(B_HAL_LPUART_1, sgUartData); HAL_UART_Receive_IT(&hlpuart1, &sgUartData, 1); } } int main() { ... bInit(); bWifiInit(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ bBUTTON_ADD_KEY(bKEYF1, BTN_EVENT_LONG, _ButtonEventHandler); bStateTransfer(STATE_OFFLINE); //默认状态,离线状态 HAL_UART_Receive_IT(&hlpuart1, &sgUartData, 1); phandle = bWifiUp(bESP12F, bWifiEventHandle); if (phandle == NULL) { b_log("handle invalid...\r\n"); } bStateTransfer(STATE_OFFLINE); if (phandle) { bStateInvokeEvent(EVENT_WIFI_INIT, phandle); } while (1) { bExec(); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } } ``` 结果: wifi_result1 ![wifi_result2](https://gitee.com/notrynohigh/BabyOS_Example/raw/BearPi/Doc/wifi_result2.png) ![wifi_result3](https://gitee.com/notrynohigh/BabyOS_Example/raw/BearPi/Doc/wifi_result3.png)
## IAP固件升级 *具体代码参考 https://gitee.com/notrynohigh/BabyOS_Example/tree/BearPi-IAP/* 固件升级使用了BabyOS的IAP功能模块。 文件传输的协议采用的是BabyOS的私有协议。 IAP的介绍文档 https://gitee.com/notrynohigh/BabyOS/wikis/ 固件升级的上位机 https://gitee.com/notrynohigh/BabyOS_Protocol ----- # 最后的话 欢迎各位单片机入门者使用BabyOS快速体验MCU功能。 欢迎各位开源爱好者共创BabyOS开源项目。