当前位置: 首页 > news >正文

在建设部网站上的举报《传奇世界》官网

在建设部网站上的举报,《传奇世界》官网,自己家的电脑宽带50m做网站服务器,wordpress大学打不开好的#xff0c;我们来举几个单片机中主循环#xff08;主程序#xff09;和中断服务程序访问共享资源#xff08;如全局变量、硬件寄存器、缓冲区等#xff09;发生冲突的典型案例#xff0c;并解释冲突是如何发生的。 核心问题#xff1a; 当主循环和中断服务程序异步…好的我们来举几个单片机中主循环主程序和中断服务程序访问共享资源如全局变量、硬件寄存器、缓冲区等发生冲突的典型案例并解释冲突是如何发生的。 核心问题 当主循环和中断服务程序异步地即发生时机不确定访问同一个资源并且至少有一个访问是“写”操作时如果访问不是“原子性”的即不能被中断打断的最小操作单元就可能出现冲突导致数据损坏、程序逻辑错误或硬件操作异常。 案例 1全局状态标志位 (Flag) 场景 系统有一个按键按下时产生外部中断。中断服务程序负责设置一个全局标志位 keyPressed 1;。主循环不断检查这个标志位如果 keyPressed 1则执行相应的处理函数 handleKeyPress()然后将标志位清零 keyPressed 0;。代码片段 (伪代码):volatile int keyPressed 0; // 必须声明为 volatile防止编译器优化掉对内存的访问// 中断服务程序 (ISR) void EXTI0_IRQHandler(void) {if (检查中断源是按键) {keyPressed 1; // 中断中设置标志位清除中断标志;} }// 主循环 void main(void) {while(1) {if (keyPressed 1) { // 主循环读取标志位handleKeyPress(); // 执行按键处理keyPressed 0; // 主循环清除标志位}// ... 其他任务 ...} }冲突发生过程 主循环执行到 if (keyPressed 1)此时 keyPressed 是 0条件不成立跳过处理部分。就在 if 语句之后keyPressed 0; 语句之前按键被按下触发中断。中断服务程序执行将 keyPressed 设置为 1。中断返回主循环继续执行 keyPressed 0; (此时它本意是清除之前可能存在的标志但实际清除了中断刚设置的新标志)。 结果 虽然按键确实被按下并触发了中断但主循环在处理完上一个按键事件后或者根本没处理立刻将中断刚设置的新标志清零了。主循环中的 if (keyPressed 1) 条件永远没有机会成立导致这次按键事件被完全丢失handleKeyPress() 永远不会被执行。根本原因 主循环检查标志位 (keyPressed 1) 和清除标志位 (keyPressed 0) 不是原子操作。中断可以在两者之间发生覆盖掉中断设置的值。 案例 2共享数据缓冲区 (Buffer) 场景 系统通过 UART 接收数据。UART 接收完成中断 (RXNE) 将接收到的字节存入一个全局环形缓冲区 rxBuffer并更新写索引 writeIndex。主循环定期检查 readIndex ! writeIndex如果不相等则从 rxBuffer 中读取一个字节根据 readIndex进行处理然后递增 readIndex。代码片段 (伪代码):#define BUFFER_SIZE 64 volatile uint8_t rxBuffer[BUFFER_SIZE]; volatile uint16_t writeIndex 0; // 中断写入位置 volatile uint16_t readIndex 0; // 主循环读取位置// UART 接收中断服务程序 (ISR) void USART1_IRQHandler(void) {if (UART1-SR RXNE) { // 检查接收寄存器非空标志uint8_t data UART1-DR; // 读取接收到的数据rxBuffer[writeIndex] data; // 写入缓冲区writeIndex (writeIndex 1) % BUFFER_SIZE; // 更新写索引} }// 主循环 void main(void) {while(1) {if (readIndex ! writeIndex) { // 检查是否有新数据uint8_t receivedData rxBuffer[readIndex]; // 读取一个字节readIndex (readIndex 1) % BUFFER_SIZE; // 更新读索引processData(receivedData); // 处理数据}// ... 其他任务 ...} }冲突发生过程 (读取损坏或重复): 主循环执行 if (readIndex ! writeIndex)假设此时 readIndex 5, writeIndex 10条件成立。主循环开始执行 uint8_t receivedData rxBuffer[readIndex]; (读取 rxBuffer[5])。就在读取 rxBuffer[5] 之后更新 readIndex 之前发生 UART 接收中断。中断服务程序执行收到一个新字节 0xAA将其写入 rxBuffer[writeIndex] (即 rxBuffer[10])然后更新 writeIndex (10 1) % 64 11。中断返回主循环继续执行 readIndex (5 1) % 64 6;。 结果 (数据丢失): 这个例子本身冲突不明显主循环成功读取了位置5的数据中断正确写入了位置10的数据并更新了写索引。主循环更新读索引到6也正确。似乎没问题 问题在于中断更新 writeIndex 和主循环更新 readIndex 都是多字节操作如果 BUFFER_SIZE 256uint16_t 在8位MCU上需要多条指令。更严重的冲突在于缓冲区满/空的判断逻辑。更严重的冲突 (缓冲区状态判断错误) 判断缓冲区是否有数据的核心是 readIndex ! writeIndex。假设缓冲区是空的 (readIndex writeIndex 15)。 主循环执行 if (readIndex ! writeIndex)此时两者相等 (15)条件不成立跳过读取。紧接着UART 中断发生写入一个字节到 rxBuffer[15]然后更新 writeIndex (15 1) % 64 16。中断返回。此时缓冲区确实有数据 (readIndex15, writeIndex16)但主循环刚刚判断过并且认为没有数据它要等到下一次检查这个条件时才会发现数据。这造成了短暂的延迟但通常可接受。更糟糕的情况 (临界区问题) 如果主循环在检查 readIndex ! writeIndex 之后读取数据之前被中断且中断导致缓冲区状态发生根本变化比如从非空变空或反之主循环基于过时的状态信息进行操作可能导致读取无效数据或写入冲突。不过环形缓冲区的设计通常能避免严重损坏但临界区保护仍是必要的。 案例 3直接操作硬件寄存器 (Peripheral Register) 场景 主循环需要配置一个定时器 (TIM) 为 PWM 输出模式并启动它。配置过程涉及写入多个寄存器 (TIMx_CR1, TIMx_CCMR1, TIMx_CCER, TIMx_ARR, TIMx_CCR1, TIMx_EGR, TIMx_CR1 再次写入启动)。同时该定时器的更新中断 (UIE) 被使能用于其他目的。中断服务程序会读取或修改定时器的某些寄存器例如读取计数器值 TIMx_CNT 或清除状态标志。代码片段 (伪代码):// 定时器更新中断服务程序 (ISR) void TIM2_IRQHandler(void) {if (TIM2-SR UIF) { // 检查更新中断标志uint16_t cntVal TIM2-CNT; // 中断中读取计数器值 (示例操作)// ... 可能还有其他操作 ...TIM2-SR ~UIF; // 清除更新中断标志} }// 主循环中配置并启动PWM void configureAndStartPWM(void) {// 1. 停止定时器 (如果正在运行)TIM2-CR1 ~TIM_CR1_CEN;// 2. 配置模式 (PWM模式1)TIM2-CCMR1 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2;// 3. 使能输出比较TIM2-CCER | TIM_CCER_CC1E;// 4. 设置自动重装载值 (周期)TIM2-ARR 999;// 5. 设置捕获比较值 (占空比)TIM2-CCR1 500;// 6. 产生更新事件 (加载预装载寄存器) - 可选但常见TIM2-EGR | TIM_EGR_UG;// 7. 清除可能挂起的更新中断标志 - 重要!TIM2-SR ~TIM_SR_UIF;// 8. 使能更新中断 (如果需要在配置后启用)// TIM2-DIER | TIM_DIER_UIE;// 9. 启动定时器TIM2-CR1 | TIM_CR1_CEN; }冲突发生过程 主循环执行到步骤 3 (TIM2-CCER | TIM_CCER_CC1E;)。就在步骤 3 之后步骤 4 之前定时器更新中断发生可能是之前配置残留或硬件原因。中断服务程序执行它读取了 TIM2-CNT (此时定时器处于一个部分配置的状态ARR, CCR1 还是旧值或未定义值)然后清除了 UIF 标志。中断返回主循环继续执行步骤 4 (TIM2-ARR 999;), 步骤 5 (TIM2-CCR1 500;) 等等。 结果 中断读取到无效数据 中断服务程序读取的 TIM2-CNT 值是在定时器配置中途进行的这个值可能毫无意义导致基于此值的后续逻辑出错。中断清除标志干扰主循环 主循环在步骤 7 尝试清除可能挂起的 UIF 标志。如果中断在第 3 步和第 7 步之间发生并清除了 UIF主循环的清除操作可能无效或不必要但也可能掩盖了真正需要在主循环中处理的状态。更严重的是如果主循环在步骤 7 之后才使能中断 (TIM2-DIER | TIM_DIER_UIE;)而中断在步骤 7 之前发生并清除了 UIF那么一个本应在配置完成后触发的中断可能就被意外清除了。硬件处于不一致状态 在步骤 1 停止定时器后到步骤 9 重新启动之前对寄存器的多次写入应该是一个“事务”。中断在这个事务中途访问寄存器看到的配置是不完整且不一致的。即使中断只是读取状态也可能读到矛盾的信息。如果中断尝试修改寄存器后果更不可预测可能导致 PWM 输出异常毛刺、错误占空比/周期、定时器计数异常甚至硬件锁定。 根本原因 对硬件寄存器的配置通常需要写入多个寄存器才能完成一个有效的、一致的功能状态。这个配置过程不是原子的。中断可以在配置过程的任意时刻插入访问或修改处于中间无效状态的硬件寄存器。 总结 这些案例清晰地展示了主循环与中断服务程序异步访问共享资源时可能发生的冲突 标志位冲突 导致事件丢失或重复处理。缓冲区冲突 导致数据损坏、丢失、重复读取或状态判断错误。硬件寄存器冲突 导致硬件行为异常、读取到无效数据或状态、配置失效。 避免冲突的关键策略 临界区保护 (Critical Sections) 在访问共享资源的代码段主循环或中断前后使用关中断 (__disable_irq() / cli()) / 开中断 (__enable_irq() / sei()) 或信号量 (Semaphore) / 互斥锁 (Mutex - 通常在RTOS中) 等手段确保访问过程不被中断或其他任务打断。(对于案例1保护 if(keyPressed) 检查和 keyPressed0 的整个区域对于案例2保护读写索引的更新对于案例3保护整个配置函数或关键步骤)原子操作 (Atomic Operations) 使用处理器支持的原子指令如ARM的 LDREX/STREX或确保数据类型在平台上能单条指令完成读写如8位MCU上的uint8_t。(对案例1的flag如果平台支持原子读写uint8_t单独读写是原子的但检查清零的组合操作仍需临界区保护)无锁编程 (Lock-Free Programming) 设计特殊的数据结构和算法如精心设计的环形缓冲区使用单独的读/写指针和镜像索引利用内存屏障确保可见性避免使用锁。这需要较高的技巧且并非所有场景都适用。禁止在中断中执行耗时操作或复杂逻辑 尽量保持中断服务程序简短只做最必要的操作如设置标志、存入缓冲区、清除中断标志复杂的处理交给主循环基于标志位去完成。这本身就能减少冲突窗口和可能性。使用 volatile 关键字 告知编译器该变量可能被意外修改如被中断修改强制每次访问都从内存读取/写入防止编译器优化导致访问不到最新值。这是解决冲突的必要条件但远非充分条件。它解决的是编译器优化带来的可见性问题解决不了上述的并发访问时序问题。 理解这些冲突场景及其根本原因是编写健壮、可靠的嵌入式系统程序的基础。务必在涉及共享资源访问的地方仔细考虑并发访问的可能性并采取适当的保护措施。
http://www.w-s-a.com/news/432921/

相关文章:

  • 大型做网站的公司有哪些wordpress注册链接无效
  • 推荐门户网站建设公司网站开发移动端
  • 公司网站的栏目设置成都十大监理公司排名
  • 安溪住房和城乡建设网站关岭县建设局网站
  • 网站域名注销备案徐州房产网
  • 筑聘网windows优化大师自动安装
  • 龙华高端网站设计门户网站建设方案公司
  • 网站开发作用网站建设哪家专业
  • 网站设计报告总结南宁商城网站推广公司
  • 淘宝做店招的网站免费网站建设自助建站
  • 重庆工信部网站绵阳公司网站建设
  • 购物网站开发流程制作企业网页
  • 定州哪里可以做网站建设项目环境影响登记表备案系统网站
  • 网站建设费属于广告费小猪网站怎么做的
  • 国内优秀设计网站站长哈尔滨微网站建设
  • 如何建设一个优秀的电商网站沐风seo
  • 从零开始学网站建设知乎安防网站下载
  • 打开网站弹出qq应用软件有哪些
  • 温州网站建设seo网站 如何做 中英文切换
  • 聊城做网站的公司资讯信阳 网站建设
  • 天津市工程建设交易网站查汗国珠海 网页设计
  • 龙果学院大型网站稳定性建设汾阳做网站
  • 湖北 个人网站备案时间域名查询备案查询
  • 网站推广方式校园网站怎么建
  • 长沙seo网站排名怎么在百度发帖
  • 织梦贷款网站模板做印章网站
  • 彭州做网站上海百度网络推广
  • 广州网站搭建快速提升网站排名荧光字网站
  • 15年做那些网站能致富做seo是什么意思
  • 各电商网站的特点网站制作2007