本帖最后由 eltonchang2001 于 2022-11-9 14:01 编辑
[url=home.php?mod=space&uid=760190]@21小跑堂 #申请原创#[/url]
腾讯物联网终端操作系统(TencentOS tiny)是腾讯面向物联网领域开发的实时操作系统,具有低功耗,低资源占用,模块化,安全可靠等特点,可有效提升物联网终端产品开发效率。TencentOS tiny 提供精简的 RTOS 内核,内核组件可裁剪可配置,可快速移植到多种主流 MCU 及模组芯片上。而且,基于RTOS内核提供了丰富的物联网组件,内部集成主流物联网协议栈(如 CoAP/MQTT/TLS/DTLS/LoRaWAN/NB-IoT 等),可助力物联网终端设备及业务快速接入腾讯云物联网平台。这是官网 https://cloud.tencent.com/product/tos-tiny,接下来开始移植。首先要准备一个带有基本外设的工程,有串口,LED灯就可以了,使用的是官方给的例子。下载TencentOS的源码,如下所示:
上面画框的是我们需要的部分,由于本次芯片是m0+的,所以在架构选择arm-v7a,删掉不用的部分,避免工程过大。接下来直接keil里面添加源码。如下所示:
源码添加完成后需要添加头文件路径
接下来特别重要的一步,需要选择C99mode ,不然编译的时候可以看到900个错误。
接下来需要对ht32f5xxxxit.h中的函数进行处理。
//void SVC_Handler(void)
//{
//}
/*********************************************************************************************************//**
* @brief This function handles PendSVC exception.
* @retval None
************************************************************************************************************/
//void PendSV_Handler(void)
//{
//}
/*********************************************************************************************************//**
* @brief This function handles SysTick Handler.
* @retval None
************************************************************************************************************/
void SysTick_Handler(void)
{
if (tos_knl_is_running())
{
tos_knl_irq_enter();
tos_tick_handler();
tos_knl_irq_leave();
}
}
接下来需要创建一个OS的配置裁剪文件,Tos_config.h
#ifndef _TOS_CONFIG_H_
#define _TOS_CONFIG_H_
#include "ht32.h" // 目标芯片头文件,用户需要根据情况更改
#include <stdio.h>
#define TOS_CFG_TASK_PRIO_MAX 10u // 配置TencentOS tiny默认支持的最大优先级数量
#define TOS_CFG_ROUND_ROBIN_EN 0u // 配置TencentOS tiny的内核是否开启时间片轮转
#define TOS_CFG_OBJECT_VERIFY_EN 1u // 配置TencentOS tiny是否校验指针合法
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u // TencentOS tiny 动态任务创建功能宏
#define TOS_CFG_EVENT_EN 1u // TencentOS tiny 事件模块功能宏
#define TOS_CFG_MMBLK_EN 1u //配置TencentOS tiny是否开启内存块管理模块
#define TOS_CFG_MMHEAP_EN 1u //配置TencentOS tiny是否开启动态内存模块
#define TOS_CFG_MMHEAP_DEFAULT_POOL_EN 1u // TencentOS tiny 默认动态内存池功能宏
#define TOS_CFG_MMHEAP_DEFAULT_POOL_SIZE 0x100 // 配置TencentOS tiny默认动态内存池大小
#define TOS_CFG_MUTEX_EN 1u // 配置TencentOS tiny是否开启互斥锁模块
#define TOS_CFG_MESSAGE_QUEUE_EN 1u // 配置TencentOS tiny是否开启消息队列模块
#define TOS_CFG_MAIL_QUEUE_EN 1u // 配置TencentOS tiny是否开启消息邮箱模块
#define TOS_CFG_PRIORITY_MESSAGE_QUEUE_EN 1u // 配置TencentOS tiny是否开启优先级消息队列模块
#define TOS_CFG_PRIORITY_MAIL_QUEUE_EN 1u // 配置TencentOS tiny是否开启优先级消息邮箱模块
#define TOS_CFG_TIMER_EN 1u // 配置TencentOS tiny是否开启软件定时器模块
#define TOS_CFG_PWR_MGR_EN 0u // 配置TencentOS tiny是否开启外设电源管理模块
#define TOS_CFG_TICKLESS_EN 0u // 配置Tickless 低功耗模块开关
#define TOS_CFG_SEM_EN 1u // 配置TencentOS tiny是否开启信号量模块
#define TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN 1u // 配置TencentOS tiny是否开启任务栈深度检测
#define TOS_CFG_FAULT_BACKTRACE_EN 0u // 配置TencentOS tiny是否开启异常栈回溯功能
#define TOS_CFG_IDLE_TASK_STK_SIZE 128u // 配置TencentOS tiny空闲任务栈大小
#define TOS_CFG_CPU_TICK_PER_SECOND 1000u // 配置TencentOS tiny的tick频率
#define TOS_CFG_CPU_CLOCK (60000000) // 配置TencentOS tiny CPU频率
#define TOS_CFG_TIMER_AS_PROC 1u // 配置是否将TIMER配置成函数模式
#endif
完成之后就可以创建线程,启动OS了,如下所示:
/*********************************************************************************************************//**
* [url=home.php?mod=space&uid=288409]@file[/url] IP/Example/main.c
* [url=home.php?mod=space&uid=895143]@version[/url] $Rev:: 4869 $
* [url=home.php?mod=space&uid=212281]@date[/url] $Date:: 2020-08-05 #$
* [url=home.php?mod=space&uid=247401]@brief[/url] Main program.
*************************************************************************************************************
* @attention
*
* Firmware Disclaimer Information
*
* 1. The customer hereby acknowledges and agrees that the program technical documentation, including the
* code, which is supplied by Holtek Semiconductor Inc., (hereinafter referred to as "HOLTEK") is the
* proprietary and confidential intellectual property of HOLTEK, and is protected by copyright law and
* other intellectual property laws.
*
* 2. The customer hereby acknowledges and agrees that the program technical documentation, including the
* code, is confidential information belonging to HOLTEK, and must not be disclosed to any third parties
* other than HOLTEK and the customer.
*
* 3. The program technical documentation, including the code, is provided "as is" and for customer reference
* only. After delivery by HOLTEK, the customer shall use the program technical documentation, including
* the code, at their own risk. HOLTEK disclaims any expressed, implied or statutory warranties, including
* the warranties of merchantability, satisfactory quality and fitness for a particular purpose.
*
* <h2><center>Copyright (C) Holtek Semiconductor Inc. All rights reserved</center></h2>
************************************************************************************************************/
// <<< Use Configuration Wizard in Context Menu >>>
/* Includes ------------------------------------------------------------------------------------------------*/
#include "ht32.h"
#include "ht32_board.h"
#include "tos_k.h"
k_task_t task;
k_stack_t task_stack[512];
void test_task(void *Parameter)
{
while(1)
{
printf("task is run!\r\n");
HT32F_DVB_LEDToggle(HT_LED1);
HT32F_DVB_LEDToggle(HT_LED2);
tos_task_delay(1000);
}
}
void NVIC_Configuration(void);
void CKCU_Configuration(void);
void GPIO_Configuration(void);
#if (ENABLE_CKOUT == 1)
void CKOUTConfig(void);
#endif
static void __Delay(u32 count);
int main(void)
{
k_err_t err;
NVIC_Configuration(); /* NVIC configuration */
CKCU_Configuration(); /* System Related configuration */
GPIO_Configuration(); /* GPIO Related configuration */
RETARGET_Configuration(); /* Retarget Related configuration */
HT32F_DVB_LEDInit(HT_LED1);
HT32F_DVB_LEDInit(HT_LED2);
HT32F_DVB_LEDInit(HT_LED3);
HT32F_DVB_LEDOn(HT_LED1);
HT32F_DVB_LEDOff(HT_LED2);
HT32F_DVB_LEDOn(HT_LED3);
printf("Welcome to TencentOS tiny\r\n");
tos_knl_init(); // TOS Tiny kernel initialize
//
err = tos_task_create(&task, "task1", test_task, NULL, 2,task_stack,512,20);
if(err != K_ERR_NONE)
printf("TencentOS Create task fail! code : %d \r\n",err);
if(err==K_ERR_NONE)
printf("TencentOS Create task success!\r\n");
tos_knl_start(); // Start TOS Tiny
}
/*********************************************************************************************************//**
* [url=home.php?mod=space&uid=247401]@brief[/url] Configure the NVIC vector table.
* @retval None
***********************************************************************************************************/
void NVIC_Configuration(void)
{
NVIC_SetVectorTable(NVIC_VECTTABLE_FLASH, 0x0); /* Set the Vector Table base location at 0x00000000 */
}
/*********************************************************************************************************//**
* @brief Configure the system clocks.
* @retval None
***********************************************************************************************************/
void CKCU_Configuration(void)
{
/*
//<e0> Enable Peripheral Clock
// <h> Communication
// <q5> EBI
// <q11> I2C0 <q12> I2C1
// <q23> I2S
// <q21> SCI0 <q22> SCI1
// <q13> SPI0 <q14> SPI1
// <q17> UART0 <q18> UART1
// <q15> USART0 <q16> USART1
// <q3> USB
// </h>
// <h> IO
// <q7> GPIO Port A <q8> GPIO Port B <q9> GPIO Port C <q10> GPIO Port D
// <q19> AFIO
// <q20> EXTI
// </h>
// <h> System
// <q32> ADC
// <q4> CKREF
// <q6> CRC
// <q31> CMP
// <q2> PDMA
// <q26> PWRCU
// </h>
// <h> Timer
// <q29> BFTM0 <q30> BFTM1
// <q33> SCTM0 <q34> SCTM1 <q35> SCTM2 <q36> SCTM3
// <q27> GPTM0 <q28> GPTM1
// <q24> MCTM0
// <q26> RTC <q25> WDT
// </h>
//</e>
*/
#if 1
CKCU_PeripClockConfig_TypeDef CKCUClock = {{ 0 }};
CKCUClock.Bit.PDMA = 0;
CKCUClock.Bit.USBD = 0;
CKCUClock.Bit.CKREF = 0;
CKCUClock.Bit.EBI = 0;
CKCUClock.Bit.CRC = 0;
CKCUClock.Bit.PA = 0;
CKCUClock.Bit.PB = 0;
CKCUClock.Bit.PC = 0;
CKCUClock.Bit.PD = 0;
CKCUClock.Bit.I2C0 = 0;
CKCUClock.Bit.I2C1 = 0;
CKCUClock.Bit.SPI0 = 0;
CKCUClock.Bit.SPI1 = 0;
CKCUClock.Bit.USART0 = 1;
CKCUClock.Bit.USART1 = 1;
CKCUClock.Bit.UART0 = 1;
CKCUClock.Bit.UART1 = 1;
CKCUClock.Bit.AFIO = 1;
CKCUClock.Bit.EXTI = 0;
CKCUClock.Bit.SCI0 = 0;
CKCUClock.Bit.SCI1 = 0;
CKCUClock.Bit.I2S = 0;
CKCUClock.Bit.MCTM0 = 0;
CKCUClock.Bit.WDT = 0;
CKCUClock.Bit.BKP = 0;
CKCUClock.Bit.GPTM0 = 0;
CKCUClock.Bit.GPTM1 = 0;
CKCUClock.Bit.BFTM0 = 0;
CKCUClock.Bit.BFTM1 = 0;
CKCUClock.Bit.CMP = 0;
CKCUClock.Bit.ADC = 0;
CKCUClock.Bit.SCTM0 = 0;
CKCUClock.Bit.SCTM1 = 0;
CKCUClock.Bit.SCTM2 = 0;
CKCUClock.Bit.SCTM3 = 0;
CKCU_PeripClockConfig(CKCUClock, ENABLE);
#endif
#if (ENABLE_CKOUT == 1)
CKOUTConfig();
#endif
}
#if (ENABLE_CKOUT == 1)
/*********************************************************************************************************//**
* @brief Configure the debug output clock.
* @retval None
***********************************************************************************************************/
void CKOUTConfig(void)
{
{ /* Enable peripheral clock */
CKCU_PeripClockConfig_TypeDef CKCUClock = {{ 0 }};
CKCUClock.Bit.AFIO = 1;
CKCU_PeripClockConfig(CKCUClock, ENABLE);
}
AFIO_GPxConfig(GPIO_PA, AFIO_PIN_9, AFIO_MODE_15);
{ /* Configure CKOUT */
CKCU_CKOUTInitTypeDef CKOUTInit;
CKOUTInit.CKOUTSRC = CKCU_CKOUTSRC_HCLK_DIV16;
CKCU_CKOUTConfig(&CKOUTInit);
}
}
#endif
/*********************************************************************************************************//**
* @brief Configure the GPIO ports.
* @retval None
***********************************************************************************************************/
void GPIO_Configuration(void)
{
/* !!! NOTICE !!!
Shall be modified according to the part number.
*/
#if (RETARGET_PORT == RETARGET_USART0)
//AFIO_GPxConfig(GPIO_PA, AFIO_PIN_2 | AFIO_PIN_3, AFIO_FUN_USART_UART);
#endif
#if (RETARGET_PORT == RETARGET_USART1)
//AFIO_GPxConfig(GPIO_PA, AFIO_PIN_4 | AFIO_PIN_5, AFIO_FUN_USART_UART);
#endif
#if (RETARGET_PORT == RETARGET_UART0)
//AFIO_GPxConfig(GPIO_PC, AFIO_PIN_4 | AFIO_PIN_5, AFIO_FUN_USART_UART);
#endif
#if (RETARGET_PORT == RETARGET_UART1)
//AFIO_GPxConfig(GPIO_PC, AFIO_PIN_1 | AFIO_PIN_3, AFIO_FUN_USART_UART);
#endif
}
#if (HT32_LIB_DEBUG == 1)
/*********************************************************************************************************//**
* @brief Report both the error name of the source file and the source line number.
* @param filename: pointer to the source file name.
* @param uline: error line source number.
* @retval None
***********************************************************************************************************/
void assert_error(u8* filename, u32 uline)
{
/*
This function is called by IP library that the invalid parameters has been passed to the library API.
Debug message can be added here.
Example: printf("Parameter Error: file %s on line %d\r\n", filename, uline);
*/
while (1)
{
}
}
#endif
/* Private functions ---------------------------------------------------------------------------------------*/
/*********************************************************************************************************//**
* @brief delay function
* @param count: delay count for loop
* @retval None
***********************************************************************************************************/
static void __Delay(u32 count)
{
while (count--)
{
__NOP(); // Prevent delay loop be optimized
}
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
接下来看串口输出的结果:
|