我们来分析一个简单的Tiny例程:
打开以后是一个巨大的程序集合,这里的话需要等一会儿,我这里使用VSCode来看代码,所以有一个建立程序各种索引的过程。
这个启动文件其实和不一样,和我们平时看的程序而言(有点倒装?)
稍微一看就会看到这个系统初始化的函数
会跳转到这里
代码语言:javascript复制#define WEAK_AV __attribute__((weak, section(".after_vectors")))
第二个main会跳转
会跳到这里,其实我们的程序从这里才差不多可以看
看下符号树
再看看引入的头文件
板子引脚的初始化工作
代码语言:javascript复制#define BOARD_USER_LED_GPIO GPIO3
会发现对应的IO都是使用的宏定义去处理的
就像这样
代码语言:javascript复制#define GPIO3
((GPIO_Type *)GPIO3_BASE)
/** Peripheral GPIO4 base address */
如果一直往下追,会发现和STM32的库是一样的封装方法
这个地方是我们的引脚的二次跳转定义
这是在储存的树上面的定义
对于引脚的初始化,需要把上面声明的引脚加进来
这里看不懂
系统时钟的处理
如果一直跟着源码追的话,会跟到这个结构体里面
这里是新建一个任务,先定义一个栈的大小
Tiny的类型系统
用一个结构体来说一个任务应该拥有哪些运行的必要数据
你这样看,就是开辟了一个数组空间
这里是创建的第一个任务,打印一个字符串
其实到目前为止来说,我们都还没有正经的干啥,都是写了点要运行的任务而已。
定义输出 LED 管脚的 init 结构
1.引脚的描述
2.输出的逻辑
3.中断模式
这是对应的要输入的结构体的描述
触发中断的几种模式,都是常见的
这个结构体会传到下面这个GPIO的初始化的函数里面
函数在此,看传入的内容
GPIO 的寄存器的定义
这里是对函数的修饰装饰
GPIO的初始化和TOS的初始化
这里就是我们的初始化的函数
代码语言:javascript复制 tos_knl_init();
// TencentOS Tiny kernel initialize
tos_task_create(&task1, "task1", task1_entry, NULL, 4, task1_stk, TASK1_STK_SIZE, 0); // Create task1
tos_task_create(&task2, "task2", task2_entry, NULL, 3, task2_stk, TASK2_STK_SIZE, 0); // Create task2
tos_knl_start();
下面是两个函数的初始化,接着启动开始运行。
启动任务以后,开始了一段循环的操作,我稍微有点看不懂。
延迟一秒
输入的参数在这里
现在是在While里面循环一下,专用的循环函数。
如果两个宏都启用了
开始就反转这个引脚。
GPIO的状态
如果启用,让GPIO写
代码语言:javascript复制(GPIO_Type *base,
uint32_t pin,
uint8_t output)
传入的参数
更改完做一个变换,将GPIO的状态改变一下。