序言
即將進入萬物互聯的時代,身邊將會湧現出一大批物聯網設備。低成本+低功耗+聯網將是最重要的需求。作爲一名習慣了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
生成代碼,則順利看到需要的代碼都已經生成:
配置
然後,就是根據文檔,修改、添加里面的文件。
生成內核文件夾Tiny
這裏有個坑:
官方文檔中提供的一個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/項目名/
在IDE中添加相關的引用
這裏首先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 */
}
至此,文件添加修改完成。
編譯
直接點擊工具欄上的錘子:
稍等一下,我們就順利編譯完成了!
由於當前沒有板子,所以沒辦法嘗試自己到底做的對不對,所以現在記錄一下,等待有板子了之後繼續下一步試驗。