话不多说,直接看我的测试源码:
// //-- main.c // #include <stdio.h> #include <stdlib.h> #include "stm32f10x.h" #include "tn.h" //-- 空闲任务栈的大小,以字为单位 17+32个字,即49个字 #define IDLE_TASK_STACK_SIZE (TN_MIN_STACK_SIZE + 32) //-- 中断堆栈大小,以字为单位 #define INTERRUPT_STACK_SIZE (TN_MIN_STACK_SIZE + 32) //-- 用户任务的堆栈大小 #define TASK_A_STK_SIZE (TN_MIN_STACK_SIZE + 32) #define TASK_B_STK_SIZE (TN_MIN_STACK_SIZE + 32) #define TASK_C_STK_SIZE (TN_MIN_STACK_SIZE + 32) //-- 用户任务优先级,0最高 #define TASK_A_PRIORITY 2 #define TASK_B_PRIORITY 3 #define TASK_C_PRIORITY 4 /******************************************************************************* * DATA ******************************************************************************/ //-- Allocate arrays for stacks: stack for idle task // and for interrupts are the requirement of the kernel; // others are application-dependent. // We use convenience macro TN_STACK_ARR_DEF() for that. TN_STACK_ARR_DEF(idle_task_stack, IDLE_TASK_STACK_SIZE); TN_STACK_ARR_DEF(interrupt_stack, INTERRUPT_STACK_SIZE); TN_STACK_ARR_DEF(task_a_stack, TASK_A_STK_SIZE); TN_STACK_ARR_DEF(task_b_stack, TASK_B_STK_SIZE); TN_STACK_ARR_DEF(task_c_stack, TASK_C_STK_SIZE); //-- 任务结构, 当成C++公有的类,task_a b c 是类实列化的对像 struct TN_Task task_a; struct TN_Task task_b; struct TN_Task task_c; /******************************************************************************* * FUNCTIONS ******************************************************************************/ //-- to printf int fputc(int c, FILE *stream) { return ITM_SendChar(c); } //-- init system timer void hw_init(void) { SysTick_Config(SYS_FREQ / SYS_TMR_FREQ); // 配置SysTick } //-- system timer 中断 void SysTick_Handler(void) { tn_tick_int_processing(); // 周期性执行 } //-- 测试IO口 void gpio_test(void) { /* GPIOD Periph clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); /* Configure PC6 in output pushpull mode */ GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOC, &GPIO_InitStructure); } //-- a task void task_a_body(void *par) { printf("New task a is OK!\n"); for(;;) { printf("task a runing...\n"); tn_task_sleep(400); } } //-- b task void task_b_body(void *par) { printf("New task b is OK!\n"); for(;;) { printf("task b runing...\n"); tn_task_sleep(400); } } //-- c task void task_c_body(void *par) { static char x=0; printf("New task c is OK!\n"); tn_task_activate(&task_b); // 在C任务中激活B任务 for(;;) { printf("task c runing...\n"); GPIO_WriteBit(GPIOC, GPIO_Pin_6, x^=1); // 反转一个IO口 tn_task_sleep(400); } } //-- 空闲回调,从空闲任务中定期调用 void idle_task_callback (void) { ; } //-- 创建应用任务, void init_task_create(void) { //-- 初始化各种板载外围设备,如闪存、显示器,等等。 //-- 初始化各种程序模块,----- 免去再建一个APP_init()函数,没必要 gpio_test(); //-- 测试IO口初始化 //-- 以下是任务建立,推介只激活一个任务,然后在该任务依次激活所有任务. tn_task_create( &task_a, //-- task structure 任务a对像的地址 task_a_body, //-- task body function 任务A的回调函数 TASK_A_PRIORITY, //-- task priority 任务A的优先级 task_a_stack, //-- task stack 任务A的堆栈地址,类似数组 TASK_A_STK_SIZE, //-- task stack size (in words) 任务A的堆栈长度 NULL, //-- task function parameter 函数参数 TN_TASK_CREATE_OPT_START //-- creation option 任务创建后是否应立即激活 ); tn_task_create( &task_b, task_b_body, TASK_B_PRIORITY, task_b_stack, TASK_B_STK_SIZE, NULL, 0//TN_TASK_CREATE_OPT_START 不激活,在C中进行激活 ); tn_task_create( &task_c, task_c_body, TASK_C_PRIORITY, task_c_stack, TASK_C_STK_SIZE, NULL, TN_TASK_CREATE_OPT_START // 激活 ); } /******************************************************************************* * 主程序入口 ******************************************************************************/ int main(void) { //-- 无条件关中断,初始化OS心跳 tn_arch_int_dis(); hw_init(); //-- 对tn_sys_start()的调用从不返回 tn_sys_start( idle_task_stack, // 空闲堆栈地址 IDLE_TASK_STACK_SIZE, // 空闲堆栈大小 interrupt_stack, // 中断栈 INTERRUPT_STACK_SIZE, // 中断栈大小 init_task_create, // 用户任务回调 idle_task_callback // 空闲任务回调 ); //-- unreachable 无法到达 return 1; }
接上STM32F10X开发板, SEGGER Embedded Studio在线仿真效果如下:
因为 GPIO_WriteBit(GPIOC, GPIO_Pin_6, x^=1)存在; 所以会看到PC6引脚上的LED在闪烁!!
空间使用多不多,下面可以参考一下,必竟抢占式使用了堆栈
清一色的堆栈改成“ +16 ”后,RAM又小一点。来说说为什么还是去裸蹦代码???
当OS系统只有空闲任务时,这就是OS占用芯片的资源了:
TASK结束了,真是无聊透顶了,尽干这些没用的东东!!