开放原子训练营(第四季)TobudOs--TobudOs基础内核学习(一)系统与任务管理

TobudOs基础内核主要分为9个要点:

  • 系统管理

系统管理模块,主要提供了内核的初始化、内核运行启动,中断进入/退出流程托管、系统调度锁定及解锁等功能。

  • 任务管理

提供了任务的创建、删除、睡眠、取消睡眠、挂起、恢复、优先级修改、主动放弃 CPU 等功能。

  • 任务间通信

提供互斥量、信号量、队列、事件等常用任务间通信机制。

  • 内存管理

提供了基于堆的动态内存管理,以及静态内存块管理机制。

  • 时间管理

提供了获取/设置系统时钟滴答数、系统时钟滴答数与墙上时钟时间转换、基于墙上时钟时间的任务睡眠等机制。

  • 软件定时器

提供了软件定时器的创建、删除、启动、停止等机制。

  • 时间片轮转机制

TencentOS tiny 内核在提供可抢占式调度内核基础上,还提供了按时间片轮转的 robin 机制。

  • 内核基础组件

提供了消息队列、字符流先入先出队列等机制。

  • 功耗管理

提供了 CPU 低功耗运行模式设置、低功耗设备注册、板级唤醒闹钟设置等机制。

学习这些基础内核可以通过阅读官方文档以及api说明:

TencentOS-tiny: TencentOS tiny 是腾讯面向物联网领域开发的实时操作系统,具有低功耗,低资源占用,模块化,安全可靠等特点,可有效提升物联网终端产品开发效率 (gitee.com)icon-default.png?t=N7T8https://gitee.com/Tencent/TencentOS-tiny

在正式编写程序前我们先熟悉下要用的api:

系统管理接口函数:

/**
 * @brief Initialize the kernel.
 * initialize the tos tiny kernel.
 */
__API__ k_err_t tos_knl_init(void);//用于初始化内核


/**
 * @brief Start the kernel.
 * get the kernel start to run, which means start the multitask scheduling.
 */
__API__ k_err_t tos_knl_start(void);//启动内核即调度器

/**
 * @brief Get the kernel state.
 * whether the kernel is running.
 * @return  whether the kernel is running.
 * @retval  Non-0                           the kernel is running.
 * @retval  0                               the kernel is not running.
 */
__API__ int     tos_knl_is_running(void);//判断内核是否启动


/**
 * @brief Kernel enter the interrupt.
 * this function should be called in the entrance of a interrupt handler.

 */
__API__ void    tos_knl_irq_enter(void);//通知内核进入中断,应在中断时开始调用
__API__ void    tos_knl_irq_leave(void);//通知内核离开中断,应在中断结束时调用

__API__ k_err_t tos_knl_sched_lock(void);//锁住调度器,此时无法切换任务
__API__ k_err_t tos_knl_sched_unlock(void);//解锁调度器

任务管理接口函数:

静态任务创建与销毁
/**
 * @brief Create a task.
 * create a task.
 *
 * @attention None
 *
 * @param[in]   task        pointer to the handler of the task.
 * @param[in]   name        name of the task.
 * @param[in]   entry       running entry of the task.
 * @param[in]   arg         argument for the entry of the task.
 * @param[in]   prio        priority of the task.
 * @param[in]   stk_base    stack base address of the task.
 * @param[in]   stk_size    stack size of the task.
 * @param[in]   timeslice   time slice of the task.
 *
 * @return  errcode
 * @retval  #K_ERR_TASK_STK_SIZE_INVALID    stack size is invalid.
 * @retval  #K_ERR_TASK_PRIO_INVALID        priority is invalid.
 * @retval  #K_ERR_NONE                     return successfully.
 */
__API__ k_err_t tos_task_create(k_task_t *task,        //任务管理块
                                const char *name,      //任务名
                                k_task_entry_t entry,  //任务入口函数
                                void *arg,             //任务参数
                                k_prio_t prio,         //任务优先级1-9以内十为空闲任务
                                k_stack_t *stk_base,   //任务栈地址
                                size_t stk_size,       //任务栈大小
                                k_timeslice_t timeslice);//时间片

__API__ k_err_t tos_task_destroy(k_task_t *task);
动态任务创建与销毁
/**
 * @brief Create a task with a dynamic allocated task handler and stack.
 * create a task with a dynamic allocated task handler and stack.
 *
 * @param[out]  task        dynamic allocated task handler.
 * @param[in]   name        name of the task.
 * @param[in]   entry       running entry of the task.
 * @param[in]   arg         argument for the entry of the task.
 * @param[in]   prio        priority of the task.
 * @param[in]   stk_size    stack size of the task.
 * @param[in]   timeslice   time slice of the task.
 *
 * @return  errcode
 * @retval  #K_ERR_TASK_STK_SIZE_INVALID    stack size is invalid.
 * @retval  #K_ERR_TASK_PRIO_INVALID        priority is invalid.
 * @retval  #K_ERR_TASK_OUT_OF_MEMORY       out of memory(insufficient heap memory).
 * @retval  #K_ERR_NONE                     return successfully.
 */
__API__ k_err_t tos_task_create_dyn(k_task_t **task,
                                                    const char *name,
                                                    k_task_entry_t entry,
                                                    void *arg,
                                                    k_prio_t prio,
                                                    size_t stk_size,
                                                    k_timeslice_t timeslice);

__API__ k_err_t tos_task_destroy_dyn(k_task_t *task);
任务延时与撤销
/**
 * @brief Delay current task for ticks.
 * Delay for a specified amount of ticks.
 *
 * @attention None
 *
 * @param[in]   delay       amount of ticks to delay.
 *
 * @return  errcode
 * @retval  #K_ERR_DELAY_ZERO     delay is zero.
 * @retval  #K_ERR_NONE           return successfully.
 */
__API__ k_err_t tos_task_delay(k_tick_t delay);//参数为系统节拍为单位

__API__ k_err_t tos_task_delay_abort(k_task_t *task);//取消任务延时

挂起任务与恢复
/**
 * @brief Suspend a task.
 * Bring a task to sleep.
 *
 * @attention None
 *
 * @param[in]   task        pointer to the handler of the task to be resume.
 *
 * @return  errcode
 * @retval  #K_ERR_TASK_SUSPEND_IDLE  attempt to suspend idle task.
 * @retval  #K_ERR_NONE               return successfully.
 */
__API__ k_err_t tos_task_suspend(k_task_t *task);

__API__ k_err_t tos_task_resume(k_task_t *task);

其他常用任务接口函数
/**
 * @brief Change task priority.
 * Change a priority of the task.
 *
 * @attention None
 *
 * @param[in]   task        pointer to the handler of the task to be resume.
 * @param[in]   prio_new    new priority.
 *
 * @return  errcode
 * @retval  #K_ERR_TASK_PRIO_INVALID  new priority is invalid.
 * @retval  #K_ERR_NONE               return successfully.
 */
__API__ k_err_t tos_task_prio_change(k_task_t *task, k_prio_t prio_new);//更改任务优先级

/**
 * @brief Quit schedule this time.
 * Quit the cpu this time.
 *
 * @attention None
 *
 * @param   None
 *
 * @return  None
 */
__API__ void    tos_task_yield(void);//当前任务放弃cpu使用权

/**
 * @brief Get the maximum stack draught depth of a task.
 *
 * @attention None
 *
 * @param[in]   task        pointer to the handler of the task.
 * @param[out]  depth       task stack draught depth.
 *
 * @return  errcode
 * @retval  #K_ERR_NONE                 get depth successfully.
 * @retval  #K_ERR_TASK_STK_OVERFLOW    task stack is overflow.
 */
__API__ k_err_t tos_task_stack_draught_depth(k_task_t *task, int *depth);//获取任务使用栈最大时的大小

/**
 * @brief Find task by task name.
 * Find task by task name.
 *
 * @param   name    the name of the task.
 *
 * @return  the matched task handler
 */
__API__ k_task_t *tos_task_find(const char *name);//通过名字获取任务块

综合实例:

#include "main.h"
#include "usart.h"
#include "gpio.h"
#include "tos_k.h"

k_stack_t task_1_stack[512];
k_task_t task_1;

k_stack_t task_2_stack[512];
k_task_t task_2;

void board_init(void)
{
	  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();
  MX_USART1_UART_Init();
}



void task_1_handler(void* parameter)
{
	uint8_t i=0;
	while(1)
	{
		if(key_scan())
		{
			i++;
		if(i==1)
		{
			tos_knl_sched_lock();
			printf("调度器已被锁住");	
		}
		else if(i==2)
		{
			tos_knl_sched_unlock();
			printf("调度器已解锁\n");
			
		}
		else if(i==3)
		{
			tos_task_delay_abort(&task_2);
			printf("解除任务2睡眠");
			
		}
		else if(i==4)
		{
			tos_task_suspend(&task_2);
				printf("挂起任务2");
		}
		else if(i==5)
		{
			tos_task_resume(&task_2);
			printf("恢复任务2\n");
		}
		else if(i==6)
		{
			int depth;
			tos_task_stack_draught_depth(&task_2,&depth);
			tos_task_destroy(&task_2);
			printf("删除任务2\n任务2最大栈深为%d字节",depth);
		}
		}
	
		tos_task_delay(10);
	}
}
void task_2_handler(void* parameter)
{
	uint8_t i=1;
	while(1)
	{
		printf("task2 is running ...%d",i++);
		HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_9);		
		tos_task_delay(2000);
	}
}
int main(void)
{
	board_init();//硬件初始化


	tos_knl_init();//初始化内核
	
	tos_task_create(&task_1,"button_task",task_1_handler,NULL,2,task_1_stack,512,100);
	tos_task_create(&task_2,"led_task",task_2_handler,NULL,1,task_2_stack,512,100);
	
	tos_knl_start();//启动调度器


}
实验现象

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值