即将进入万物互联的时代,身边将会涌现出一大批物联网设备。低成本+低功耗+联网将是最重要的需求。作为一名习惯了Linux上开发软件的程序猿,深感压力。适逢国产物联网正大力宣传,借此东风开始学习物联网操作系统上的开发工作。
未来将记录几篇学习的文章,即为了沉淀知识,也为了给后进场的程序猿们提供一条道路。希望自己能够坚持下去,实现一点点价值。
如无特别声明,均是在苹果MacOS下进行。
TencentOS-Tiny 是腾讯开发的一款物联网操作系统,相关基础知识和介绍就不啰嗦,直接上手源码。
源码位置在https://github.com/Tencent/TencentOS-tiny.git
进入自己的工作目录,git clone https://github.com/Tencent/TencentOS-tiny.git
源码体积很小,使用命令 du -sh
看到,一共635M
源码结构比较简洁:
TencentOS-tiny git:(master) ✗ tree -L 1
.
├── LICENSE
├── README.md
├── arch
├── board
├── components
├── devices
├── doc
├── examples
├── kernel
├── net
├── osal
├── platform
├── test
└── tools
首先就进入doc目录,查看相关的文档。
doc git:(master) ✗ ls
1.TencentOS tiny产品简介.md TencentOS-tiny-porting-gcc.md
2.TencentOS tiny购买指南_免费版.md TencentOS-tiny-porting-iar.md
3.TencentOS tiny快速入门.md TencentOS-tiny-porting-keil.md
4.TencentOS-tiny开发指南.md TencentOS-tiny-代码目录说明.md
5.TencentOS-tiny-SDK文档.md TencentOS-tiny定制开发板入门指南.pdf
6.TencentOS tiny常见问题.md code
7.TencentOS tiny词汇表.md img
8.TencentOS-tiny对接腾讯云IoTHub开发指南.md picture
TencentOS-tiny-porting(MacOS_STM32CubeIDE).md
作为MacOS,我最关心的就是如何快速编译系统,并在系统中愉快的开发软件。所以第一步,先查阅《TencentOS-tiny-porting(MacOS_STM32CubeIDE).md》
看了内容,发现需要下载工具 STM32CubeIDE 于是到官网进行下载。不过下载前需要注册帐号,这个没办法,先注册一个。这里我放到百度云盘上了,链接:https://pan.baidu.com/s/1js586SiS-n4Vx025TrYuLw 密码:qs41 这个软件比较大,我下载的版本是1.0.2,下载好了大约 881.6M。
下载好了则开始进行安装,这个很简单。简单说一下,这个IDE是基于Eclipse进行开发的,很庆幸我之前使用过Eclipse做过java和C,还用它做过Android开发,算是轻车熟路。
进了界面,会选择一个工作目录,未来创建的项目都会存储到这个文件夹下,这里我选了默认目录
进入到主界面之后,就可以看到欢迎界面
这里点击左边蓝色按钮 开始一个新的STM32项目。这时会出现我第一个坑:它需要更新下载文件。不知道什么情况,我一直没更新下来,我就点了取消。
然后就需要选择硬件芯片的型号了,这里我按照官方开发板的指示选择了L431RC这个型号
先是在左边搜索芯片型号,右边选择具体的型号,点击下一步。输入项目名字。继续点击下一步,完成。
然后会蹦出来这么一个窗口.我也不知道干啥的,感觉像是更新什么。
这里开始,就进入了我的知识盲区……这都是啥……看官方文档……各种配置,也不管那么多,都不配置呗,默认就好了吧,想点击下一步,可是找来找去,没有找到啊?!跟官方说明不一样啊?!什么情况,后来在工具栏上找到了这么一个选项:
点击!注意,又一个我踏了坑:又要更新!居然是700多M!
惊呆我。网络也不知道怎么回事,几kb的下载,这要下载到猴年马月?醉了。
经过几次不断的尝试,我发现了有这么一个配置,也不知道对不对,有没有影响,反正我就是这么改了,然后好了!
终于可以愉快的下载了,下载好的文件,默认放在家目录下:
➜ Repository pwd
/Users/lee/STM32Cube/Repository
➜ Repository ls
PRSTM32MP10219-01-med.jpg bd_stm32l431xx.jpg
STM32Cube_FW_L4_V1.14.0_bk stm32cube_fw_l4_v1140_bk.zip
原本想在这里复现一下原来的情况,抓个图,把下载好的包改了名字,可是等我重新打开IDE发现仍然能够加载,也是奇怪了。
这里我把下载包stm32cube_fw_l4_v1140.zip
也共享出来吧,提供给一些下载异常的朋友 链接:https://pan.baidu.com/s/1J6yxZmLOKhn-gg1wgQgHfQ 密码:liry
下载完成后,重新点击Generate code
生成代码,则顺利看到需要的代码都已经生成:
然后,就是根据文档,修改、添加里面的文件。
这里有个坑:
官方文档中提供的一个shell文件:TencentOS-tiny/tools/make_mac_stm32cubeide_code.sh,执行之后会把当前文件夹给删除掉!
我在源码目录中全局搜索这个关键名,grep "make_mac_stm32cubeide" . -rn
没有找到相关介绍,也很诧异,不知道具体什么情况,也不知道啥用法,可能是我没找对位置吧。这里只是提醒朋友们别失误执行了这个文件导致文件丢失。
20190929更新
根据官方的 issue #23 原来是由内网转换到外网出现了部分代码提交异常,所以相关的文档并没有提交上去,具体情况可以点链接进去看一下,中文交流。
并且也知晓了错误原因:内网项目命名为TencentOS_tiny 提交到github时更名为了TencentOS-tiny. 导致部分文件有这样的问题。
我提交了PR已经更改了此文件,现版本已经可以直接在tools目录下直接使用。
这里呢,参考官方文档《TencentOS-tiny-porting(MacOS_STM32CubeIDE).md》 将对应的文件拷贝到新的文件夹,文件夹目录为:
➜ tiny tree -d
.
├── arch
│ └── arm
│ └── arm-v7m
│ ├── common
│ │ └── include
│ └── cortex-m4
│ └── gcc
├── kernel
│ ├── core
│ │ └── include
│ ├── evtdrv
│ │ └── include
│ ├── hal
│ │ └── include
│ └── pm
│ └── include
└── osal
└── cmsis_os
18 directories
然后,将这个目录,拷贝到之前创建的项目文件夹中。项目文件夹默认目录为:/Users/用户名/STM32CubeIDE/workspace_1.0.2/项目名/
这里首先F5刷新一下项目,然后,添加头文件包含关系:
这里我们都是使用的相对路径。具体需要包含的文件有:
tiny/arch/arm/arm-v7m/common/include/
tiny/arch/arm/arm-v7m/cortex-m4/gcc/
tiny/kernel/core/include/
tiny/kernel/pm/include/
tiny/osal/cmsis_os/
tiny/kernel/evtdrv/include/ #注意,这个官方文档中没有
文件都配置好了之后,我们开始添加文件。
在Inc目录下新建一个头文件tos_config.h
#ifndef _TOS_CONFIG_H_
#define _TOS_CONFIG_H_
#include "stm32l431xx.h" // 目标芯片头文件,视特定芯片而定
#include "stddef.h"
#define TOS_CFG_TASK_PRIO_MAX 10u // 配置TencentOS tiny默认支持的最大优先级数量
#define TOS_CFG_ROUND_ROBIN_EN 1u // 配置TencentOS tiny的内核是否开启时间片轮转
#define TOS_CFG_OBJECT_VERIFY 0u // 配置TencentOS tiny是否校验指针合法
#define TOS_CFG_EVENT_EN 1u // TencentOS tiny 事件模块功能宏
#define TOS_CFG_MMHEAP_EN 1u // 配置TencentOS tiny是否开启动态内存模块
#define TOS_CFG_MMHEAP_POOL_SIZE 0x100 // 配置TencentOS tiny动态内存池大小
#define TOS_CFG_MUTEX_EN 1u // 配置TencentOS tiny是否开启互斥锁模块
#define TOS_CFG_QUEUE_EN 1u // 配置TencentOS tiny是否开启队列模块
#define TOS_CFG_TIMER_EN 1u // 配置TencentOS tiny是否开启软件定时器模块
#define TOS_CFG_SEM_EN 1u // 配置TencentOS tiny是否开启信号量模块
#if (TOS_CFG_QUEUE_EN > 0u)
#define TOS_CFG_MSG_EN 1u
#else
#define TOS_CFG_MSG_EN 0u
#endif
#define TOS_CFG_MSG_POOL_SIZE 10u // 配置TencentOS tiny消息队列大小
#define TOS_CFG_IDLE_TASK_STK_SIZE 256u // 配置TencentOS tiny空闲任务栈大小
#define TOS_CFG_CPU_TICK_PER_SECOND 1000u // 配置TencentOS tiny的tick频率
#define TOS_CFG_CPU_CLOCK (SystemCoreClock) // 配置TencentOS tiny CPU频率
#define TOS_CFG_TIMER_AS_PROC 1u // 配置是否将TIMER配置成函数模式
#endif
修改Src/stm32l4xx_it.c
里的代码:
将void PendSV_Handler(void)
修改为__weak void PendSV_Handler(void)
在SysTick_Handler
函数中HAL_IncTick();
之后添加代码
if(tos_knl_is_running()) {
tos_knl_irq_enter();
tos_tick_handler();
tos_knl_irq_leave();
}
修改Src/main.c
添加代码:
#include "cmsis_os.h"
//task1
#define TASK1_STK_SIZE 512
void task1(void *pdata);
osThreadDef(task1, osPriorityNormal, 1, TASK1_STK_SIZE);
//task2
#define TASK2_STK_SIZE 512
void task2(void *pdata);
osThreadDef(task2, osPriorityNormal, 1, TASK2_STK_SIZE);
void task1(void *pdata)
{
while(1)
{
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
osDelay(200);
}
}
void task2(void *pdata) {
while(1) {
osDelay(1000);
}
}
注意:因为之前我没有配置硬件具体的接口,这里需要配置一下,具体的位置在Inc/main.h
里添加:
#define LED_Pin GPIO_PIN_13
#define LED_GPIO_Port GPIOC
在Src/main.c
文件中添加:
static void MX_GPIO_Init(void);
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : LED_Pin */
GPIO_InitStruct.Pin = LED_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct);
}
主函数代码:
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
osKernelInitialize(); //TOS Tiny kernel initialize
osThreadCreate(osThread(task1), NULL); // Create task1
osThreadCreate(osThread(task2), NULL); // Create task2
osKernelStart(); //Start TOS Tiny
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
至此,文件添加修改完成。
由于当前没有板子,所以没办法尝试自己到底做的对不对,所以现在记录一下,等待有板子了之后继续下一步试验。