IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 单片机系统编程学习总结 -> 正文阅读

[嵌入式]单片机系统编程学习总结

TreeOS学习总结

TreeOS在自我介绍时说自己提出的一种面向场景编程的构件化方法,解决了标准化系统软件架构的问题。TreeOS是一种无核的软件构件化的、实时嵌入式操作系统。
笔者觉得的这是一种前后台系统(文章后面会解释什么是前后台),它对于编程各个任务让我错乱的我提供了特别大的帮助,目前网上相关的代码很少,我通过官网找到了它的两百页的使用指南,大受裨益。如果你也是苦恼于单片机各个任务的管理,或者在准备电赛的程序,这里强烈推荐大家阅读它前80页内容。[TREEOS操作指南]
构件化方法 大循环前后台系统
多道程序系统运行
系统失败曲线
就像和《疯狂动物城》里的闪电对话一样
TREEOS开发步骤
Treeos层次结构
任务运行过程
定时器中断中的显示—按键结合函数可以在公共while中调用,以节约中断资源

场景子场景的子场景编写规范。
为提高编程效果,当A为主场景时。与B同级的场景,如B1、B2等建议分成不同的.C和.H文件,但对于场景B而言,C和D可看作相同.C文件中的不同任务,通过不同函数来实现,再通过switch来选择调用。
场景结构图
这种多级树形结构可将任务持续细化,但也规定了必须有且只有一个主场景。但是如果持续细化任务嵌套导致过于占用堆栈。

常用的单片机裸机程序框架

如果不上操作系统的话(如freetos 、rt-thread ),裸机框架其实可以完成各种任务,并且系统非常考验处理器的性能,也会占用过多的资源。所以我打算还是主要学习逻辑框架。以下学习来自野火的《RT-Thread内核实现与应用开发实践指南》

1.轮询系统

最常用也是最简单的一种方法,没有外部事件时常用。

int main(void)
{
    init_something();
    
    while(1)
    {
        do_something1();
        do_something2();
        do_something3();
    }
}

2.前后台系统

前后台系统是在轮询系统的基础上加入了中断。外部事件的响应在中断里面完成,事件的处理还是回到轮询系统中完成,中断在这里我们称为前台,main 函数里面的无限循环我们称为后台。
特点:事件的响应和处理分开,事件的处理还是在后台里面顺序执行的,但相比轮询系统,前后台系统
确保了事件不会丢失,再加上中断具有可嵌套的功能,这可以大大的提高程序的实时响应能力

int flag1 = 0;
int flag2 = 0;
int flag3 = 0;
?
int main(void)
{
 /* 硬件相关初始化 */
 HardWareInit();
?
 /* 无限循环 */
 for (;;) {
   if (flag1) {
     /* 处理事情 1 */
     DoSomething1();
   }
?
   if (flag2) {
     /* 处理事情 2 */
     DoSomethingg2();
   }
?
   if (flag3) {
     /* 处理事情 3 */
     DoSomethingg3();
   }
 }
}
?
void ISR1(void)
{
 /* 置位标志位 */
 flag1 = 1;
 /* 如果事件处理时间很短,则在中断里面处理
 如果事件处理时间比较长,在回到后台处理 */
 DoSomething1();
}
?
void ISR2(void)
{
 /* 置位标志位 */
 flag2 = 2;
?
 /* 如果事件处理时间很短,则在中断里面处理
 如果事件处理时间比较长,在回到后台处理 */
 DoSomething2();
}
?
void ISR3(void)
{
 /* 置位标志位 */
 flag3 = 1;
 /* 如果事件处理时间很短,则在中断里面处理
 如果事件处理时间比较长,在回到后台处理 */
 DoSomething3();
}

3.多线程系统

相比前后台系统,多线程系统的事件响应也是在中断中完成的,但是事件的处理是在线程中完成的。在多线程系统中,线程跟中断一样,也具有优先级,优先级高的线程会被优先执行。当一个紧急的事件在中断被标记之后,如果事件对应的线程的优先级足够高,就会立马得到响应。相比前后台系统,多线程系统的实时性又被提高了。
线程:在多线程系统中,根据程序的功能,我们把这个程序主体分割成一个个独立的,无限循环且不能返回的小程序,这个小程序我们称之为线程。每个线程都是独立的,互不干扰的,且具备自身的优先级,它由操作系统调度管理。

int flag1 = 0;
int flag2 = 0;
int flag3 = 0;
int main(void)
{
/* 硬件相关初始化 */
HardWareInit();
/* OS 初始化 */
RTOSInit();
/* OS 启动,开始多线程调度,不再返回 */
RTOSStart();
}
void ISR1(void)
{
/* 置位标志位 */
flag1 = 1;
}
void ISR2(void)
{
/* 置位标志位 */
flag2 = 2;
}
void ISR3(void)
{
/* 置位标志位 */
flag3 = 1;
}
void DoSomething1(void)
{
/* 无限循环,不能返回 */
	for (;;)
	{
	/* 线程实体 */
	if (flag1) {
				}
	}
}
void DoSomething2(void)
{
/* 无限循环,不能返回 */
for (;;)
{
	/* 线程实体 */
	if (flag2) {
				}	
	}
}
void DoSomething3(void)
{
/* 无限循环,不能返回 */
	for (;;)
	{
	/* 线程实体 */
	if (flag3) {
				}
	}
}

三种系统比较

系统重要概念

临界段

临界段用一句话概括就是一段在执行的时候不能被中断的代码段。在系统里面,这个临界段最常出现的就是对全局变量的操作,全局变量就好像是一个枪把子,谁都可以对他开枪,但是我开枪的时候,你就不能开枪,否则就不知道是谁命中了靶子。
那么什么情况下临界段会被打断?一个是系统调度,还有一个就是外部中断。在进入临界段之前,我们会先把中断关闭,退出临界段时再把中断打开。
在STM32中,简单粗暴的方法就是直接:

//进入临界段
   INTX_DISABLE();
.....................
//退出临界段
	INTX_ENABLE();   

共享资源

这里通俗来讲就是不同场景之间的全局变量,多个任务共同使用的资源叫做共享资源(如数据、文件、输入输出设备等)。为了防止数据被破坏或设备异常,每个任务使用共享资 源时,必须独占该资源,不能被打断。最常用的做法是先关中断,运行临界区代码,然后重新开中断。

阻塞与非阻塞赋值

这段概念来源于学习FPGA,若大家想深入了解可以参考正点原子的FPGA教程。

阻塞:
阻塞
非阻塞
非阻塞

拆分与拆分技术

学习来自treeos:
对于运行时间长、实时性要求不高的普通任务,可以拆分成两部分或两部分以上的任务,而每部分运行时间都较短。每次循环只运行其中的一部分,多次运行才能获得结果。这实际上是一种多道系统的处理方法,也称为分时调度。
例如,对键盘可以通过多次循环扫描的方法,监控按键释放动作出现后再进行处理。这样可以避免占用处理 器长时间延时等待的问题。拆分技术可以减少循环总时间。 拆分技术会经常用到。 而对于实时性要求较高的普通任务,可以在任务顺序队列中插入两次或两次以上的运行机会,使任务的实时性要求获得满足。插入技术使循环总时间增加。例如,在一个场景中,任务顺序队列完成一次循环最大时间需要 50ms,而某个任务则需要 30ms 内执行一次,那么 就可以采用这种插入技术,使该任务的实时性要求获得满足。

底半处理(优先任务=中断标志+while触发任务)

尽管嵌入式系统对中断程序处理时间一般不做限制,但是普遍的做法是尽量缩短中断处理时间,以免影响其它中断服务或紧急任务。 一种有效的做法是把中断处理任务过程分为两部分,上半部分(top half)处理紧急事务,例如设置标志或者接收输入数据单元,这部分运行时间很短,放在中断服务程序中进行。然后把一些需耗时处 理或对时间要求不太紧急的事务放在之后运行(例如放在后台程序 中),这部分程序称为底半部分(bottom half)。

下一次会总结一下状态机的学习经验

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-12 16:46:05  更:2021-08-12 16:48:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 20:51:38-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码