975|2

171

帖子

10

TA的资源

一粒金砂(高级)

《Rust实战》读书笔记——第12章,信号、中断和异常 [复制链接]

作者延续上一章的风格,demo级的介绍,帮助理解概念入门。

12_01.png

说实话,真没啥好解释的,中断就是程序跑着跑着,突然CPU接到了什么神谕,然后就对程序说“你站在此地不要动,我去买几个橘子”,直到cpu忙完了,程序才敢接着跑。

可以引入asm特性,像c一样嵌入汇编直接调软中断。

 

信号是操作系统特性,举的例子是SIGSTOP是暂停执行SIGCONT是继续执行。

可以用libc的signal、raise来自定义信号处理方式(libc::signal(信号名, 处理函数);)、发出信号。

 

本书最后一个例子加进了一个知识点——rust支持setjmp、longjmp这种操作:

#![feature(link_llvm_intrinsics)]
#![allow(non_camel_case_types)]
#![cfg(not(windows))]

use libc::{
  SIGALRM, SIGHUP, SIGQUIT, SIGTERM, SIGUSR1,
};
use std::mem;

const JMP_BUF_WIDTH: usize =
  mem::size_of::<usize>() * 8;
type jmp_buf = [i8; JMP_BUF_WIDTH];

static mut SHUT_DOWN: bool = false;
static mut RETURN_HERE: jmp_buf = [0; JMP_BUF_WIDTH];
const MOCK_SIGNAL_AT: usize = 3;

extern "C" {
  #[link_name = "llvm.eh.sjlj.setjmp"]
  pub fn setjmp(_: *mut i8) -> i32;

  #[link_name = "llvm.eh.sjlj.longjmp"]
  pub fn longjmp(_: *mut i8);
}

#[inline]  
fn ptr_to_jmp_buf() -> *mut i8 {
  unsafe { &RETURN_HERE as *const i8 as *mut i8 }
}

#[inline]    
fn return_early() {
  let franken_pointer = ptr_to_jmp_buf();
  unsafe { longjmp(franken_pointer) }; 
}

fn register_signal_handler() {
  unsafe {
    libc::signal(SIGUSR1, handle_signals as usize);
  }
}

#[allow(dead_code)]
fn handle_signals(sig: i32) {
  register_signal_handler();

  let should_shut_down = match sig {
    SIGHUP => false,
    SIGALRM => false,
    SIGTERM => true,
    SIGQUIT => true,
    SIGUSR1 => true,
    _ => false,
  };

  unsafe {
    SHUT_DOWN = should_shut_down;
  }

  return_early();
}

fn print_depth(depth: usize) {
  for _ in 0..depth {
    print!("#");
  }
  println!();
}

fn dive(depth: usize, max_depth: usize) {
  unsafe {
    if SHUT_DOWN {
      println!("!");
      return;
    }
  }
  print_depth(depth);

  if depth >= max_depth {
    return;
  } else if depth == MOCK_SIGNAL_AT {
    unsafe {
      libc::raise(SIGUSR1);
    }
  } else {
    dive(depth + 1, max_depth);
  }
  print_depth(depth);
}

fn main() {
  const JUMP_SET: i32 = 0;

  register_signal_handler();

  let return_point = ptr_to_jmp_buf();
  let rc = unsafe { setjmp(return_point) };
  if rc == JUMP_SET {
    dive(0, 10);
  } else {
    println!("early return!");
  }

  println!("finishing!")
}

就是这些。

 

此帖出自编程基础论坛

最新回复

rust干这些活太别扭了,能干,但是不好干。   详情 回复 发表于 2024-6-25 11:56

回复
举报

663

帖子

5

TA的资源

纯净的硅(高级)

中断、信号、异常是cpu与系统外设通信的重要手段,理解这几个概念对有效控制外围硬件设备非常重要

此帖出自编程基础论坛

回复

7166

帖子

2

TA的资源

五彩晶圆(中级)

rust干这些活太别扭了,能干,但是不好干。

此帖出自编程基础论坛
个人签名

默认摸鱼,再摸鱼。2022、9、28


回复
您需要登录后才可以回帖 登录 | 注册

猜你喜欢
随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
推荐帖子
“大学生电子设计竞赛”版块试行版规

本帖最后由 paulhyde 于 2014-9-15 09:17 编辑 Dear all: 欢迎大家来到我们电子工程世界“大学生电子设计竞赛”版块,我有幸成 ...

Luminary系列所有型号的选型工具

Luminary的函数库和图形库,上面集成的东西很丰富,很多工程师都会喜欢。 可以按着对外设的需求,来选。想要USB,就点“USB ...

基于mega8的简易循迹小车

放假啦,回到家了。上学期遗留了一些问题。 上学期做了一个基于mega8的简易循迹小车,循黑线行驶。车模是淘宝里购买的,控制电 ...

DIY个ImxRT1010板子,硬件调试经验分享

本帖最后由 RCSN 于 2019-12-8 22:59 编辑 根据上上帖子,楼主买了MIMXRT1010-EVK板子 帖子https://bbs.eeworld.com.cn/threa ...

放大后波形产生振荡,是什么原因?

利用运放进行脉冲波形放大,后端带的是容性负载,根据使用要求需要改变脉冲波形的上升时间,下降时间等参数。发现上升时间设置小 ...

[HPM-DIY]openmv for hpm6750 仓库开源

花了差不多10天的时间,把openmv较新版本V4.3.0移植到hpm6750上来,有先楫官方hpm6750evkmini直接可以上手,安装最新openmvide即 ...

逛展全攻略 | 11.6-8深圳年度芯片×封测×嵌入式大展终于来了!

654493 ELEXCON 2022 深圳国际电子展暨嵌入式系统展 第六届中国系统级封装大会暨展览 在全力做好疫情防 ...

有奖直播|赋能移动电源,贝能推出1800W全数字双向电源方案 进行中!

有奖直播|赋能移动电源,贝能推出1800W全数字双向电源方案 进行中! >>点击进入直播 直播时间:2023年07月20 ...

《奔跑吧Linux内核(第2版)卷1:基础架构》配套实验环境搭建

本帖最后由 maskmoo 于 2023-12-13 23:38 编辑 本文主要记录对《奔跑吧Linux内核》第二版的配套实验平台环境搭建和测试过程。 ...

起早了,5点就行了,6点半就到公司了

起早了,5点就行了,6点半就到公司了,可是做到了早睡早起了,昨天7点就睡着了,结果6点半就到公司,成为了开门人,结果还没给送 ...

关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表