关于STM32的裸机多任务多线程心得

本文介绍了单片机中多任务并行处理的概念和技术,通过将任务分解为多个线程,实现资源的有效分配与利用。文章详细阐述了如何使用线程进行任务管理,包括线程的创建、调度和执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

多任务多线程

多任务"并行处理"

首先我们来理解一下并行处理,初学者写程序通常是顺序执行,当我们逐渐想成为“专业”人士的时候顺序执行 的程序已经不能满足我们了,所以就需要多任务多线程系统,市面上标准的一些操作系统比如ucos,freeRTOS这些操作系统需要的学习周期长,范围广。在网上看到了一本书"单片机编程魔法师之高级裸编思想"在没学会ucos的阶段学习用这种思想过度感觉非常nice!
单片机是支持多任务同时并行地运行在一个系统中,在具体介绍之前先看一看单片机的硬件结构
在这里插入图片描述
这个图中我们可以看出,单片机的运行是在ALU的主导下进行的;而定时器指是一个定时装置,它在定时计数期间是无需ALU干预的,完全独立运行;串口的通讯单元对数据的接收与发送也是完全独立完成的,并不需要ALU干预。很显然这三个任务是并行处理,切互不干涉,只有在定时器或串口产生中断时才会到代码中临时运行一段程序,已向单片机的主体运行过程交付一下结果,以便进行汇总处理。

微操作系统

简单一点来说就是一个while(1)但是while中我们采用多任务多线程的方式管理。首先我们要知道任务有生死,生死是一个过程所以具有寿命。
一个任务的线程:假设一个任务的执行代码有50步,通常编程只会一次执行完毕,但是我们现在需要想想,因为我们会嫌这个任务总占用着ALU的时间而影响其他任务的执行效果,所以就可以对任务进行划分,把它分为5份,每份10步,这样我们每次执行其中的一个程序片–每次正在运行的程序片我们称为线程。
在这里插入图片描述
这个图很完美的解释了线程的运行原理。
具体线程的实现:

typedef struct{
	u8 isTask_Living;
	u8 Thread_Process;
}myTask;
void Task(void)
{
	if(Task.isTask_Living)
	{
	Task.isTask_Living = !myThread3(&Task3,&Task3.Thread_Process);
	}
}
/*初始化任务变量*/
void InitTask4(myTask4 *Task)
{
	Task->isTask_Living=1;
	Task->Thread_Process=0;
}

/*功能:任务线程
**参数:myTask:Task任务类型
**	  :Process:unsigned char*类型,线程指针
**返回值:CHAR类型,线程结束,或未结束
*/
static int myThread(myTask *Task,unsigned char *Process)
{
	int ret=0;
	switch(*Process)
	{
		case 0:
		//程序片1
		break;
		case 1:
		//程序片2
		break;
		case 2:
		//程序编3
		break;
		default:break;
	}
	(*Process)++;
	if(*Process>3)
	{
		ret = -1;
		*Process = 0;
	}
	return ret;
}

void TaskCommunication(void)
{
	if(Task.isTask_Living)
	{
	Task.isTask_Living = !myThread(&Task4,&Task4.Thread_Process);
	}
}

在这里插入图片描述
在这里插入图片描述
真正多任务处理的过程:
在这里插入图片描述
仔细理解图上的内容对写多任务程序的结构很有好处。
加油吧骚年们!

### 嵌入式软件工程师实习周记模板 以下是针对嵌入式软件工程师实习生设计的一份通用周记模板,旨在帮助记录每周的工作进展、学习成果以及遇到的问题。 --- #### **第X周 实习周记** **日期范围**: YYYY-MM-DD 至 YYYY-MM-DD **本周目标**: 简要描述本周的主要工作任务和预期达成的目标。例如,“熟悉项目的整体架构并完成模块A的功能测试。” **已完成工作**: 1. 描述具体完成了哪些任务,包括但不限于代码编写、调试、文档阅读等。 - 示例:完成了UART通信协议的实现,并通过串口工具验证了数据传输功能[^1]。 2. 如果涉及多个子任务,请逐条列出并说明每项工作的具体内容及其重要性。 **学习心得**: 分享在工作中学到的新知识或技能,可以是技术层面的内容(如某种算法的应用),也可以是非技术方面的经验(如团队协作技巧)。 - 示例:深入理解了ARM Cortex-M系列微控制器中断机制的设计原理,进一步掌握了如何优化实时系统的响应速度[^2]。 **存在问题及解决方案**: 列举本周遇到的技术难题或其他障碍,并阐述解决方法或者计划采取何种措施克服这些困难。如果没有完全解决问题,则需注明当前进展情况及下一步打算。 - 示例:遇到了内存分配不连续导致的数据丢失问题;经过查阅资料发现可以通过调整结构体成员顺序来改善缓存命中率从而缓解该现象[^3]。 **下周计划**: 制定下一周的具体安排,明确即将开展的任务清单和个人成长方向。 - 示例:继续完善现有驱动程序接口函数,同时尝试移植Linux内核到目标平台之上以便支持更复杂应用需求。 --- ### 示例填充版 #### **第三周 实习周记** **日期范围**: 2023-09-04 至 2023-09-10 **本周目标**: 全面了解项目背景和技术栈,初步参与部分基础编码环节。 **已完成工作**: 1. 学习了STM32CubeMX工具链的基础操作流程,能够独立配置GPIO引脚模式及时钟树参数设置。 2. 编写了简单的LED闪烁控制逻辑作为入门练习案例,在实际硬件上运行成功验证效果正常。 3. 对接收到的一个小型实验课题进行了前期调研分析,明确了后续开发路径图谱框架思路。 **学习心得**: 通过对MCU内部寄存器映射关系的学习认识到低层编程对于提升效率有着不可替代的作用;另外还了解到版本控制系统Git的基本命令集有助于提高多人合作环境下的文件管理能力。 **存在问题及解决方案**: 初次接触裸机环境下无操作系统支撑情况下面临诸多挑战比如缺少标准库支持使得某些常用API无法直接调用必须自行封装适配层才能满足特定场景需求——目前正参考官方手册逐步摸索构建属于自己的辅助类库集合以降低重复劳动强度加快迭代周期进度。 **下周计划**: 着手搭建基于FreeRTOS的操作系统框架模型探索多线程并发执行条件下资源竞争规避策略研究最佳实践方案。 --- ```c // 示例代码片段:简单 LED 控制 void led_init(void){ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); // 启用 GPIOC 的时钟 GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13; // 设置 PC13 引脚 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出模式 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // 输出速度为 50 MHz GPIO_Init(GPIOC, &GPIO_InitStruct); } void toggle_led(void){ static uint8_t state = 0; if(state == 0){ GPIO_SetBits(GPIOC, GPIO_Pin_13); // 打开 LED state = 1; } else{ GPIO_ResetBits(GPIOC, GPIO_Pin_13); // 关闭 LED state = 0; } } ``` ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GZFSJK

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值