【OS】L17信号量临界区保护

靠临界区来保护信号量,靠信号量来实现进程间的同步;
同步就是进程间的走走停停;

“AND NEVER REMOVE THIS EMPTY LOOOP!!!”

临界区保护的三种解法

面包店算法

// Peterson 算法 :标记+轮转的结合(针对两个进程)
flag[i] = true;
turn = j;
while (flag[i] && turn == j);
临界区
flag[i] = false;
剩余区

// 面包店算法:标记+轮转的结合(针对多个进程)

choose[i] = true;
num[i] = max(num[0] + ... + num[i - ]) + 1;			// 进行取号操作
choose[i] = false;

for (int j = 0; j < n; j++) {
	while (choose[j]);			// 如果j进程在等待,则i进程空转
	while (num[j] != 0 && (num[j], j) < (num[i], i));			// 如果j进程部位0, 且j进程号 < i进程号,则i进程空转;
}
临界区
num[i] = 0;

开关中断

被调度:另一个进程只有被调度才能执行,才可能进入临界区,如何阻止调度?
通过开关中断,不去读取中断信号

cli();
	临界区
cti();
	剩余区

缺点:多核CPU不好使;

临界区保护的硬件原子指令法(多CPU情况不好使)

// 硬件原子指令
boolean TestAndSet(boolean &x)
{
		boolean rv = x;
		x = true;
		return rv;
}

while (TestAndSet(&lock));
临界区
lock = false;
剩余区

进程Pi

内容概要:文章详细介绍了HarmonyOS的目录结构及其重要性,从整体框架到核心目录的具体功能进行了全面剖析。HarmonyOS凭借其分布式架构和跨设备协同能力迅速崛起,成为全球操作系统领域的重要力量。文章首先概述了HarmonyOS的背景和发展现状,强调了目录结构对开发的重要性。接着,具体介绍了根目录文件、AppScope、entry和oh_modules等核心目录的功能和作用。例如,AppScope作为全局资源配置中心,存放应用级的配置文件和公共资源;entry目录是应用的核心入口,负责源代码和界面开发。此外,文章还对比了HarmonyOS与Android、iOS目录结构的异同,突出了HarmonyOS的独特优势。最后,通过旅游应用和电商应用的实际案例,展示了HarmonyOS目录结构在资源管理和代码组织方面的应用效果。; 适合人群:具备一定编程基础,尤其是对移动操作系统开发感兴趣的开发者,包括初学者和有一定经验的研发人员。; 使用场景及目标:①帮助开发者快速理解HarmonyOS的目录结构,提高开发效率;②为跨设备应用开发提供理论和技术支持;③通过实际案例学习资源管理和代码组织的最佳实践。; 其他说明:HarmonyOS的目录结构设计简洁明了,模块职责划分明确,有助于开发者更好地管理和组织代码和资源。随着万物互联时代的到来,HarmonyOS有望在开发便利性和生态建设方面取得更大进展,吸引更多开发者加入其生态系统。
### HC32L17上配置和使用FreeRTOS的方法 在HC32L17芯片上配置和使用FreeRTOS涉及多个方面的工作,包括硬件初始化、时钟设置、堆栈管理以及钩子函数的处理等。以下是详细的说明: #### 1. 硬件环境准备 HC32L17是一款基于ARM Cortex-M0+内核的低功耗微控制器。为了适配FreeRTOS,在项目创建初期需完成以下工作: - 配置系统时钟:确保系统的主时钟频率满足应用需求,并将其传递给CMSIS-Core层以便正确计算Systick定时器的时间间隔[^1]。 - 初始化外设:根据具体应用场景初始化串口、GPIO或其他必要的外设。 #### 2. FreeRTOS移植层编写 FreeRTOS需要针对目标MCU进行特定的移植操作,主要包括以下几个部分: - **portable目录下的文件修改** 在`portable/GCC/ARM_CM0`路径下找到对应的端口文件(如`port.c`),并调整其中的关键参数以匹配HC32L17的具体特性。例如,定义堆栈增长方向、中断优先级分组等。 - **vPortSetupTimerInterrupt()实现** 此函数用于初始化SysTick计数器作为时间基准源。对于HC32L17而言,可能还需要额外考虑其内部RC振荡器精度或者外部晶振输入的影响。 #### 3. 自定义配置选项 编辑`FreeRTOSConfig.h`头文件来设定适合当前项目的各项参数值。一些重要的宏定义如下所示: ```c #define configCPU_CLOCK_HZ ( SystemCoreClock ) /* 使用实际的核心时钟 */ #define configTICK_RATE_HZ (( TickType_t )1000)/* 定义滴答频率为每秒一千次 */ #define configMAX_PRIORITIES (5u) /* 设置最大优先级数目 */ #define configMINIMAL_STACK_SIZE ((unsigned short)128)/* 最小任务堆栈大小 */ #define configTOTAL_HEAP_SIZE ((size_t)(3 * 1024))/* 整体可用内存池容量 */ // 关闭未使用的钩子函数支持 #define configUSE_IDLE_HOOK pdFALSE #define configUSE_TICK_HOOK pdFALSE ``` #### 4. 创建第一个任务 当上述准备工作完成后就可以着手建立初始的任务单元了。下面给出一段简单的例子展示如何启动一个基础线程: ```c void vTaskFunction(void* pvParameters){ while(1){ // 执行某些业务逻辑... vTaskDelay(pdMS_TO_TICKS(100)); // 延迟一百毫秒后再继续运行 } } int main(){ xTaskCreate(vTaskFunction,"My Task",configMINIMAL_STACK_SIZE,NULL,priority,&pxCreatedTask); vTaskStartScheduler(); // 启动调度程序 for(;;); // 如果到达这里则表明出现了严重错误 } ``` #### 5. 处理潜在链接问题 正如之前提到过的那样,如果遇到诸如“Undefined symbol”的连接阶段错误,则可以按照两种方式之一加以修正——要么禁用那些不必要的回调接口;要么提供默认版本而不做实质性动作即可消除此类警告消息。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值