精华内容
下载资源
问答
  • 判断正确的是【单选题】由曲面围成或由曲面和平面围成的立体称为曲面立体,如圆柱体由圆形平面和柱面构成,圆环体由圆环面构成,圆锥体由【判断题】若圆柱体的底面为水平面,则圆柱体的三面投影是一圆和两大小相等的...

    【简答题】

    【单选题】某基本体的三视图及相关数据,判断正确的是

    【单选题】由曲面围成或由曲面和平面围成的立体称为曲面立体,如圆柱体由圆形平面和柱面构成,圆环体由圆环面构成,圆锥体由

    【判断题】若圆柱体的底面为水平面,则圆柱体的三面投影是一个圆和两个大小相等的矩形。

    【单选题】平面截切圆柱,当截平面与轴线平行时,截交线为

    【判断题】平面与正圆锥体截交,当截交线为椭圆时,截平面的位置与圆锥上所有素线相交。

    【简答题】4. Shaukat Ali: _____________________________________________

    【单选题】下图所示圆锥被正垂面P所截,其截交线的形状是

    【简答题】

    【单选题】下图为球面被两个正垂面切割,其切口的空间形状是

    【简答题】3. Michael Murphy: ______________________________________________

    【其它】7。7 8.8

    【简答题】

    【单选题】下图所示圆柱被两平面所截切,切口的空间形状是

    【单选题】下图中已知圆锥表面上一点M的正面投影m',补画其水平投影m的不正确作图方法是

    【简答题】

    【论述题】Listen to the passage again and answer the questions. How big is Sofia and Yaroslaw's farm? 2. What do the people in Sofia's hometown eat most? 3. What is the weather like in Jose's hometown? 4. What do Jose's children like to eat?

    【论述题】自拟二题

    【判断题】6. Teaching Japanese is a difficult job.

    【简答题】

    【简答题】

    【单选题】曲面体是指表面由曲面或平面和曲面围成的立体,下列不属于曲面体的是

    【单选题】如图所示,形体的H面、V面投影,正确的W面投影是

    【单选题】下图所示圆锥被正垂面P所截,其截交线的形状是

    【单选题】若圆锥体的底面为水平面,则圆锥体的三面投影是

    【简答题】

    【简答题】

    【单选题】下图为截切后正圆柱的三面投影,正确的H面投影是

    【论述题】第四章3.4,5题

    【简答题】2. Moses Agba: __________________________________________

    【简答题】Listen to the passage again. Write about each person's job and their comments(评述). Natsuko Mori:_______________________________________

    【单选题】下图中已知圆锥表面上一点M的正面投影m',补画其水平投影m的不正确作图方法是

    【判断题】平面与圆球相交,截交线的三面投影均为圆。

    【判断题】当截平面倾斜于圆柱体轴线时,截交线形状为椭圆。

    【单选题】下图为截切后正圆柱的三面投影,正确的W面投影是

    【单选题】正圆锥被一平面截切,截交线为椭圆时,截平面的位置为

    【单选题】选择形体正确的 W 面投影图

    【判断题】圆柱被平面截切后产生的截交线,因截平面与圆柱轴线的相对位置不同而有3种不同的形状。

    【单选题】下列基本体中,三视图有两个相同另一个不同的是

    【判断题】当截平面倾斜于圆锥体轴线时,截交线形状一定为椭圆。

    【单选题】下图为截切后正圆锥的正面投影,它的两段截交线是

    【单选题】以矩形的一条边为轴,其余的边绕轴旋转而成的回转体称为

    【判断题】任何截交线都具有封闭性和共有性

    【其它】1、实训的地点 2、实训的目的和意义 3、实训的内容: 导游词的创作、导游讲解的技巧、导游的服务、导游的姿态、突发事件的处理等。具体参见教案,在资料一栏下载查看。 4、实训感想和心得体会 5、不足之处有哪些 6、字体:宋体;字号:四号;标题不加粗; 7、字数要求:1500字

    【判断题】7. Moses isn’t happy.

    【判断题】8. These people like their jobs.

    【单选题】下图所示K点在球面上的位置是

    【判断题】球体的三面投影都是圆。

    【简答题】

    【单选题】圆锥被平面截切后产生的截交线,因截平面与圆锥轴线的相对位置不同而有( )不同的形状。

    展开全文
  • linux中断流程总结

    2021-07-14 13:17:59
    首先,我们要明确一点,hwirq与virq并不是一回事,hwirq就是硬件中断号,比如用户按键、串口中断、网络中断等这些,都会在gic通用中断控制器中标识出一个中断号,是属于硬件层面的序号。 为什么不直接使用hwirq呢?...

    本篇文章是基于linux-4.9.88内核进行分析,使用的单板是imx6ull。

    1、linux中断所涉及的各种数据结构关系

    首先,我们要明确一点,hwirq与virq并不是一回事,hwirq就是硬件中断号,比如用户按键、串口中断、网络中断等这些,都会在gic通用中断控制器中标识出一个中断号,是属于硬件层面的序号。

    为什么不直接使用hwirq呢?对于驱动工程师而言,我们和CPU视角是一样的,我们只希望得到一个IRQ number,而不关系具体是那个interrupt controller上的那个HW interrupt ID。这样一个好处是在中断相关的硬件发生变化的时候,驱动软件不需要修改。因此,linux kernel中的中断子系统需要提供一个将HW interrupt ID映射到IRQ number上来的机制,就是irq_domain结构的作用。

     从上图中可以看到,linux中断所涉及到的各个数据结构,主要是通过irq_desc这个结构进行链接

    • 用户申请到的每一个中断都会为它分配一个irq_desc结构。
    • irq_chip结构主要用来执行中断的各种操作,比如,屏蔽中断和使能中断
    • irq_domain结构主要用来保存hwirq和virq的映射关系,其中有两个重要的函数,.xlate和.map。
    • irq_desc结构中的handle_irq与action链表中的函数不是同一个函数,处理不同的事件,而用户注册的中断服务函数是action链表中的一个函数。

     2、异常向量表的注册

    我们知道,当发生某一个中断时,CPU就会跳转到相应的异常入口中去执行异常函数,而中断也是异常的一种,因此,我们有必要分析一下异常向量表的注册。

    arch/arm/kernel/entry-armv.S
    	.section .vectors, "ax", %progbits
    .L__vectors_start:
    	W(b)	vector_rst
    	W(b)	vector_und
    	W(ldr)	pc, .L__vectors_start + 0x1000
    	W(b)	vector_pabt
    	W(b)	vector_dabt
    	W(b)	vector_addrexcptn
    	W(b)	vector_irq
    	W(b)	vector_fiq

    这些就是各种异常发生时跳转到的函数,其中中断发生会跳转到vector_irq中,下面就去查找vector_irq,结果是找不到的,它是一个宏,

    	vector_stub	irq, IRQ_MODE, 4
    
    	.long	__irq_usr			@  0  (USR_26 / USR_32)
    	.long	__irq_invalid			@  1  (FIQ_26 / FIQ_32)
    	.long	__irq_invalid			@  2  (IRQ_26 / IRQ_32)
    	.long	__irq_svc			@  3  (SVC_26 / SVC_32)
    	.long	__irq_invalid			@  4
    	.long	__irq_invalid			@  5
    	.long	__irq_invalid			@  6
    	.long	__irq_invalid			@  7
    	.long	__irq_invalid			@  8
    	.long	__irq_invalid			@  9
    	.long	__irq_invalid			@  a
    	.long	__irq_invalid			@  b
    	.long	__irq_invalid			@  c
    	.long	__irq_invalid			@  d
    	.long	__irq_invalid			@  e
    	.long	__irq_invalid			@  f

    将 'stub'替换为 'irq'就是我们中断的跳转入口,对于user模式下,我们会跳转到__irq_usr这个位置,相应的svc模式下,将会跳转到__irq_svc的位置去执行,下面搜索__irq_usr

    	.align	5
    __irq_usr:
    	usr_entry            /* 1. 保存现场 */
    	kuser_cmpxchg_check
    	irq_handler          /* 2. 处理 */
    	get_thread_info tsk
    	mov	why, #0
    	b	ret_to_user_from_irq    /* 3. 恢复现场 */
     UNWIND(.fnend		)
    ENDPROC(__irq_usr)

    因此,irq_handler函数来处理中断,继续搜索

    	.macro	irq_handler
    #ifdef CONFIG_MULTI_IRQ_HANDLER
    	ldr	r1, =handle_arch_irq
    	mov	r0, sp
    	badr	lr, 9997f
    	ldr	pc, [r1]
    #else
    	arch_irq_handler_default
    #endif
    

    最终会执行到handle_arch_irq函数,这是在gic中设置的一个函数。在讲解如何设置该函数之前先看异常向量表是怎么让内核知道的。

    // arch\arm\kernel\head.S
    1. bl	__lookup_processor_type
       ...... 
    2. bl	__create_page_tables
    3. ldr	r13, =__mmap_switched
    4. b	__enable_mmu
       b	__turn_mmu_on
       mov	r3, r13
       ret	r3
    5. __mmap_switched: // arch\arm\kernel\head-common.S
    6. b	start_kernel
    start_kernel // init\main.c
        setup_arch(&command_line); // arch\arm\kernel\setup.c
    		paging_init(mdesc);    // arch\arm\mm\mmu.c
    			devicemaps_init(mdesc); // arch\arm\mm\mmu.c
    				vectors = early_alloc(PAGE_SIZE * 2); // 1.分配新向量表
    				early_trap_init(vectors);             // 2.从代码把向量表复制到新向量表
                        	memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
    	                    memcpy((void *)vectors + 0x1000, __stubs_start, __stubs_end - __stubs_start);
    				// 3. 映射新向量表到虚拟地址0xffff0000
                    /*
                     * Create a mapping for the machine vectors at the high-vectors
                     * location (0xffff0000).  If we aren't using high-vectors, also
                     * create a mapping at the low-vectors virtual address.
                     */
                    map.pfn = __phys_to_pfn(virt_to_phys(vectors));
                    map.virtual = 0xffff0000;
                    map.length = PAGE_SIZE;
                #ifdef CONFIG_KUSER_HELPERS
                    map.type = MT_HIGH_VECTORS;
                #else
                    map.type = MT_LOW_VECTORS;
                #endif
                    create_mapping(&map);

     在启动内核时,将中断向量表安装到内核对应的位置上,当发生异常时,便会跳转到对应的入口函数那里。

     3、handle_arch_irq函数的设置过程

    在第二节中,我们知道,当发生了中断后,经过一系列的跳转后,会执行到handle_arch_irq函数,而这个函数我们并没有设置,下面,分析一下handle_arch_irq的设置过程是怎么样的。

    如果我们搜索handle_arch_irq的话,就会看到

    arch/arm/kernel/irq.c
    void __init set_handle_irq(void (*handle_irq)(struct pt_regs *))
    {
    	if (handle_arch_irq)
    		return;
    
    	handle_arch_irq = handle_irq;
    }

    继续搜索set_handle_irq()函数,一步步往上找。

    gic_of_init
        ||
        \/
        gic_init_bases
            ||
            \/
            set_handle_irq

    在函数gic_init_bases()中,我们会看到对handle_irq的设置

    set_handle_irq(gic_handle_irq);
    
    drivers/irqchip/irq-gic.c
    static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
    

    终于找到了这个函数,因此,当中断发生时,就会调用到这个函数来处理

    gic_handle_irq
    ---->handle_domain_irq
    -------->__handle_domain_irq
    ------------>generic_handle_irq
    ---------------->generic_handle_irq_desc
    -------------------->desc->handle_irq(desc);

    最终会通过desc结构体找到我们用户注册的中断服务函数,执行中断函数。那么,问题来了,没有人调用gic_of_init()函数,我们也就不会执行到这一步,下面看谁会调用gic_of_init()函数呢?

    经过搜索的话,我们最终会找到gic_of_init()这个函数。而这个函数是这样的

    IRQCHIP_DECLARE(gic_400, "arm,gic-400", gic_of_init);
    IRQCHIP_DECLARE(arm11mp_gic, "arm,arm11mp-gic", gic_of_init);
    IRQCHIP_DECLARE(arm1176jzf_dc_gic, "arm,arm1176jzf-devchip-gic", gic_of_init);
    IRQCHIP_DECLARE(cortex_a15_gic, "arm,cortex-a15-gic", gic_of_init);
    IRQCHIP_DECLARE(cortex_a9_gic, "arm,cortex-a9-gic", gic_of_init);
    IRQCHIP_DECLARE(cortex_a7_gic, "arm,cortex-a7-gic", gic_of_init);
    IRQCHIP_DECLARE(msm_8660_qgic, "qcom,msm-8660-qgic", gic_of_init);
    IRQCHIP_DECLARE(msm_qgic2, "qcom,msm-qgic2", gic_of_init);
    IRQCHIP_DECLARE(pl390, "arm,pl390", gic_of_init);

    这个宏定义了一系列的GIC通用中断控制器,其中也包括了我们IMX6ULL用的 “arm,cortex-a7-gic”。将这个宏展开后

    IRQCHIP_DECLARE(cortex_a7_gic, "arm,cortex-a7-gic", gic_of_init);
    展开后得到:
    static const struct of_device_id __of_table_cortex_a7_gic		\
    	__used __section(__irqchip_of_table)			\
    	 = { .compatible = "arm,cortex-a7-gic",				\
    		 .data = gic_of_init  }

    我们看到,我们的gic被内核安置在 '__irqchip_of_table' 段中,按照内核一贯的习性,它会把具有相同性质的函数放入段中,用一个循环挨个执行。那么谁会执行这个段里的函数的呢?这就需要搜索 '__irqchip_of_table'了。

    drivers/irqchip/irqchip.c
    void __init irqchip_init(void)
    {
    	of_irq_init(__irqchip_of_table);
    	acpi_probe_device_table(irqchip);
    }
    
    of_irq_init
    {
        ....
        for_each_matching_node_and_match{
        ....
        }
        ....
    }

    ok,正是这个函数,for_each_matching_node_and_match()函数会逐一调用 '__irqchip_of_table' 段里的一系列gic控制器。虽然找到了这里,但是,问题又来了,是谁调用了irqchip_init()函数呢?我们继续搜索一下irqchip_init(),看一下它的调用过程。

    start_kernel
    ---->init_IRQ
    -------->irqchip_init
    ------------>of_irq_init

    看来还是要由我们繁忙的start_kernel()来调用呀。

    linux的中断过程就逐渐缕清楚了。

    4、通用中断控制器gic

    gic很关键的函数就是gic_of_init函数,我们先大致分析下gic_of_init函数是做什么的?

     对于gic来讲,有四个点需要注意下:

    • gic的处理函数,来判断是哪一个hwirq。
    • gic的domain,用来建立hwirq与virq的映射关系。
    • 如何区分是哪一个GPIO产生的中断。
    • 提供irq_chip结构体。
    gic_of_init
        ...
        ret = gic_of_setup(gic, node);
        ...
        ret = __gic_init_bases(gic, -1, &node->fwnode);
        ...
        gic_cnt++;
        ...

    分别获取中断控制器的gic中的distributor相关的寄存器组和CPU interface相关的寄存器组。

    __gic_init_bases
    {
        set_handle_irq(gic_handle_irq);	/* gic_handle_irq向量表用到的函数 会在entry_armv.S函数中调用 */
        gic_init_chip(gic, NULL, name, false);	/* 函数中含有irq_chip的设置,中断用的函数,比如屏蔽中断 使能中断 */
        ret = gic_init_bases(gic, irq_start, handle);	/* 函数中含有创建域的函数,附加上域的操作函数 */
    }
    gic_init_chip
    {
        /* Initialize irq_chip */
    	gic->chip = gic_chip;	/* gic的关键函数 */
    	gic->chip.name = name;
    	gic->chip.parent_device = dev;
        ....
    }

    提供irq_chip结构体 

    gic_init_bases
    {
        .....
        if(handle)
        {
            gic->domain = irq_domain_create_linear(handle, gic_irqs, &gic_irq_domain_hierarchy_ops, gic);
        }
        else
        {
            irq_base = irq_alloc_descs(irq_start, 16, gic_irqs, numa_node_id());
            gic->domain = irq_domain_add_legacy(NULL, gic_irqs, irq_base, hwirq_base, &gic_irq_domain_ops, gic);
        }
        ....
    }

    创建domain域。

    5、自己编写一个虚拟中断控制器gic

    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/clk.h>
    #include <linux/err.h>
    #include <linux/init.h>
    #include <linux/interrupt.h>
    #include <linux/io.h>
    #include <linux/random.h>
    #include <linux/irq.h>
    #include <linux/irqdomain.h>
    #include <linux/irqchip/chained_irq.h>
    #include <linux/platform_device.h>
    #include <linux/pm_runtime.h>
    #include <linux/slab.h>
    #include <linux/gpio/driver.h>
    /* FIXME: for gpio_get_value() replace this with direct register read */
    #include <linux/gpio.h>
    #include <linux/of.h>
    #include <linux/of_device.h>
    #include <linux/bug.h>
    #include <linux/random.h>
    
    static struct irq_domain *virtual_intc_domain;
    
    static int virtual_intc_get_hwirq(void)
    {
    	return get_random_int() & 0x3;
    }
    
    static void virtual_intc_irq_handler(struct irq_desc *desc)
    {
    	/* 它的功能时分辨是哪一个hwirq, 调用对应的irq_desc[].handle_irq */
    	u32 irq_stat;
    	int hwirq;
    	
    	struct irq_chip *chip = irq_desc_get_chip(desc);
    
    	chained_irq_enter(chip, desc);
    
    	/* a. 分辨中断 */
    	hwirq = virtual_intc_get_hwirq();
    
    	/* b. 调用irq_desc[].handle_irq(handleC) */
    	generic_handle_irq(irq_find_mapping(virtual_intc_domain, hwirq));
    
    	chained_irq_exit(chip, desc);
    }
    
    static void virtual_intc_irq_ack(struct irq_data *data)
    {
    	printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    }
    
    static void virtual_intc_irq_mask(struct irq_data *data)
    {
    	printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    }
    
    static void virtual_intc_irq_mask_ack(struct irq_data *data)
    {
    	printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    }
    
    static void virtual_intc_irq_unmask(struct irq_data *data)
    {
    	printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    }
    
    static void virtual_intc_irq_eoi(struct irq_data *data)
    {
    	printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    }
    
    static struct irq_chip virtual_intc_irq_chip = {
    	.name			= "100ask_virtual_intc",
    	.irq_ack	   = virtual_intc_irq_ack	   ,
    	.irq_mask	   = virtual_intc_irq_mask	   ,
    	.irq_mask_ack  = virtual_intc_irq_mask_ack ,
    	.irq_unmask    = virtual_intc_irq_unmask   ,
    	.irq_eoi	   = virtual_intc_irq_eoi	   ,
    };
    
    static int virtual_intc_irq_map(struct irq_domain *h, unsigned int virq,
    			  irq_hw_number_t hw)
    {
    	/* 1. 给virq提供处理函数
    	 * 2. 提供irq_chip用来mask/unmask中断
    	 */
    	
    	irq_set_chip_data(virq, h->host_data);
    	irq_set_chip_and_handler(virq, &virtual_intc_irq_chip, handle_edge_irq); /* handle_edge_irq就是handleC */
    	//irq_set_nested_thread(virq, 1);
    	//irq_set_noprobe(virq);
    
    	return 0;
    }
    
    
    static const struct irq_domain_ops virtual_intc_domain_ops = {
    	.xlate = irq_domain_xlate_onetwocell,
    	.map   = virtual_intc_irq_map,
    };
    
    static int virtual_intc_probe(struct platform_device *pdev)
    {	
    	struct device_node *np = pdev->dev.of_node;
    	int irq_to_parent;
    	int irq_base;
    	
    	/* 1. virutal intc 会向GIC发出n号中断 */
    	/* 1.1 从设备树里获得virq_n */
    	irq_to_parent = platform_get_irq(pdev, 0);
    	
    	
    	/* 1.2 设置它的irq_desc[].handle_irq, 它的功能时分辨是哪一个hwirq, 调用对应的irq_desc[].handle_irq */
    	irq_set_chained_handler_and_data(irq_to_parent, virtual_intc_irq_handler, NULL);
    
    	
    	/* 2. 分配/设置/注册一个irq_domain */
    	irq_base = irq_alloc_descs(-1, 0, 4, numa_node_id());
    
    	virtual_intc_domain = irq_domain_add_legacy(np, 4, irq_base, 0,
    					     &virtual_intc_domain_ops, NULL);
    	
    	return 0;
    }
    static int virtual_intc_remove(struct platform_device *pdev)
    {
    	return 0;
    }
    
    
    
    static const struct of_device_id virtual_intc_of_match[] = {
    	{ .compatible = "virtual_intc", },
    	{ },
    };
    
    
    static struct platform_driver virtual_intc_driver = {
    	.probe		= virtual_intc_probe,
    	.remove		= virtual_intc_remove,
    	.driver		= {
    		.name	= "virtual_intc",
    		.of_match_table = of_match_ptr(virtual_intc_of_match),
    	}
    };
    
    
    /* 1. 入口函数 */
    static int __init virtual_intc_init(void)
    {	
    	printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    	/* 1.1 注册一个platform_driver */
    	return platform_driver_register(&virtual_intc_driver);
    }
    
    
    /* 2. 出口函数 */
    static void __exit virtual_intc_exit(void)
    {
    	printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    	/* 2.1 反注册platform_driver */
    	platform_driver_unregister(&virtual_intc_driver);
    }
    
    module_init(virtual_intc_init);
    module_exit(virtual_intc_exit);
    
    MODULE_LICENSE("GPL");

    设备树

    /{
       virtual_intc: virtual_intc_100ask {
            compatible = "virtual_intc";
    
            interrupt-controller;
            #interrupt-cells = <2>;
    
            interrupt-parent = <&intc>;
            //interrupts = <GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH>;    // stm32mp157
            interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;  // imx6ull
    
        };
    
        gpio_keys_100ask {
            compatible = "gpio_key";
            interrupt-parent = <&virtual_intc>;
            interrupts = <0 IRQ_TYPE_LEVEL_HIGH>,
                         <1 IRQ_TYPE_LEVEL_HIGH>,
                         <2 IRQ_TYPE_LEVEL_HIGH>,
                         <3 IRQ_TYPE_LEVEL_HIGH>;
        };
        
    };

    展开全文
  • 四、8259A 的初始化命令字 8259A 初始化编程时,有四个初始化命令字ICW(Initialiation Command Word),即ICW1?ICW4 ;8259A工作期间,有三个操作命令字OCW(Operation Command Word),即OCW1~OCW3。 8259A 只有两个...

    四、8259A 的初始化命令字 8259A 初始化编程时,有四个初始化命令字ICW(Initialiation Command Word),即ICW1?ICW4 ;8259A工作期间,有三个操作命令字OCW(Operation Command Word),即OCW1~OCW3。 8259A 只有两个端口地址 A0= 0 偶地址端口 1 奇地址端口 因此,对8259A读/写操作时,要注意控制字 写入的端口地址 写入的顺序 有关的标志位 1. ICW1 (IRi 触发方式,是否单片使用,是否写入ICW4) 0 ? ? ? 1 LTIM ? SNGL IC4 A0 D7 D6 D5 D4 D3 D2 D1 D0 标志位 ① LTIM:规定IRi的触发方式 1高电平触发 0 触发 = ② SNGL:是否单片使用 1单片使用 0级联使用 = ③ IC4:是否写入ICW4 1后面写入ICW4 0不写入ICW4 = 例:某8086微机系统中,使用单片8259A,中断请求信号为上升沿触发,需要设置ICW4,端口地址为20H,21H,则其初始化命令字ICW1应为13H,设置ICW1的指令为: MOV  AL,13H OUT  20H,AL 2. ICW2 (中断类型号的高5位) (中断类型号的低3位由8259A 自动编码产生) 1 T7 T6 T5 T4 T3 ? ? ? A0 D7 D6 D5 D4 D3 D2 D1 D0 IRi 对应中断类型号的高5位 T7 T6 T5 T4 T3 T2 T1 T0 由ICW2规定 0 0 0 0 0 1 0 1 0 ? 1 1 1 IR0 IR1 IR2 ? IR7 例:某PC机中8个可屏蔽中断(IR0 ? IR7)的类型号为08H ? 0FH,A0=1,端口地址为21H,则ICW2为:08H,设置ICW2的指令为: MOV  AL,08H OUT  21H,AL 3. ICW3 (级联时,主从芯片的级联引脚) 若ICW1 中SNGL= 1不写入ICW3 0写入ICW3 (1) 写给主片的ICW3 Si = 1, 表示主片IRi上接有从片。 1 S7 S6 S5 S4 S3 S2 S1 S0 A0 D7 D6 D5 D4 D3 D2 D1 D0 (2) 写给从片的ICW3 ID2 ID1 ID0 该从片 0 0 0 接入主片的IR0 0 0 1 接入主片的IR1 ? ? 1 1 1 接入主片的IR7 1 0 0 0 0 0 ID2 ID1 ID0 A0 D7 D6 D5 D4 D3 D2 D1 D0 从片的标志码 例:某8086微机系统中,主片8259A的IR2,IR6引脚上分别接有从片8259A,则主、从片的ICW3初始化命令字设置如下: 主片初始化命令字:(口地址设为20H, 21H) MOV  AL,44H   ;44H为主片的ICW3,表示其IR6,IR2上接有从片 OUT  21H,AL    ;将ICW3写入奇地址端口 从片1的初始化命令:(口地址为30H,31H) MOV  AL,02H OUT  31H,AL 从片2的初始化命令:(口地址为40H,41H) MOV  AL,06H OUT  41H,AL 4. ICW4 1 0 0 SFNM BUF M/S AEOI 1 A0 D7 D6 D5 D4 D3 D2 D1 D0 0 标志位 用于8088/ 8086系统 0 正常的完全嵌套方式 1 特殊的完全嵌套方式 (1) SFNM: 规定8259A中断的嵌套方式 (单片使用时,两种方式一样。) SFNM= ① 正常的完全嵌套方式 高级的中断 ② 特殊的完全嵌套方式 同级的或高级的中断 注意:级联使用时,某一从片的IRi对主片来说是同级的(同级中断)。 此处,要理解同级中断的概念! (to CPU) INTA INT 从8259A IR7 IR6 … IR0 IR7 IR6 … IR0 INTA INT CAS0 CAS1 CAS2 CAS0 CAS1 CAS2 主8259A INTA (from CPU) INTR … … 例如: 若主、从8259A工作于固定优先权方式,从片的优先级为IR0?IR1 ?? IR7。但对主片来说,从片的IR0 ~IR7 是同级的。 1缓冲方式 0非缓冲方式 (2) BUF = (3) M/S ① 当8259A 工作于缓冲方式时 (BUF=1) , M/S用于定义主、从芯片。 1主8259A

    展开全文
  • 在程序设计时,循环直接的跳转显得十分重要,虽然Java没有提供goto语句去控制程序的跳转,但为了控制循环,Java提供了continue,break,以及特殊的标签来实现特定的中断及跳转,当然还有return,这相对不同一些。...

    在程序设计时,循环直接的跳转显得十分重要,虽然Java没有提供goto语句去控制程序的跳转,但为了控制循环,Java提供了continue,break,以及特殊的标签来实现特定的中断及跳转,当然还有return,这个相对不同一些。本篇将会做出总结。

    break

    在循环时,如果不想等到false就终止循环的话,可以使用break来完成。

    例如以下这个简单的例子:

    for (int i = 0;i<10 ;i++ ) {

    System.out.println(i);

    if(i==1) break;

    }

    System.out.println("跳出循环");//输出 0 1 跳出循环

    可以直到,如果没有if(i==1) break;这个语句,这个循环将会依次输出0-9的数字,但是加上这句之后,如果执行到i等于1时,执行break语句,将直接跳出循环。

    continue

    continue有点像是放弃一部分,再从头开始。

    依旧给出例子:

    for (int i = 0;i<10 ;i++ )

    {

    if(i%2==0) continue;

    System.out.println(i);

    }

    System.out.println("跳出循环");

    //输出1 3 5 7 9 跳出循环

    continue用于忽略本次循环剩下的语句,接着下一次循环,但是不会像break一样直接终止循环。

    上面的例子,只要时偶数就跳过后面的输出环节,后面也就都是输出奇数啦。

    return

    其实return并不是专门用于结束循环的关键字,而是用来结束一个方法。

    for (int i = 0;i<10 ;i++ ) {

    System.out.println(i);

    if(i==1) return;

    }

    System.out.println("跳出循环");//输出 0 1

    可以看出,将第一个break语句的例子改成return,后面的“跳出循环”并不会被输出,也就是说return结束了整个程序。

    虽然return也可以结束一个循环,但是与前两个不同,他结束了整个方法,不管return藏在多少层嵌套循环里面。

    return与break和continue不同的地方有很多,return后面可以跟一个值,并将值返回。

    标签

    Java中没有goto但是,continue和break两个本属于中断语句的关键字,配合上“标签”之后,有了和goto类似实现跳转的机制,能够轻易控制多层的循环嵌套。

    break和continue配合标签类似,但也有差别。

    标签需要放在循环语句之前,否则有啥意义吖,具体形式如:label:

    break+标签

    outer:

    for (int i = 0;i<5 ;i++ ) {

    for (int j = 0;j<3 ;j++ ) {

    System.out.print(" i="+i+" j="+j);

    if(j==1)

    {

    break outer;

    }

    System.out.println();

    }

    }

    //输出

    i=0 j=0

    i=0 j=1

    当j==1时,遇到break outer语句,导致结束outer标签指定的循环,不是结束break所在的循环!不是结束break所在的循环!!!!

    continue+标签

    outer:

    for (int i = 0;i<5 ;i++ ) {

    for (int j = 0;j<3 ;j++ ) {

    System.out.print(" i="+i+" j="+j);

    if(j==1)

    {

    continue outer;

    }

    System.out.println();

    }

    }

    //输出

    i=0 j=0

    i=0 j=1 i=1 j=0

    i=1 j=1 i=2 j=0

    i=2 j=1 i=3 j=0

    i=3 j=1 i=4 j=0

    i=4 j=1

    j的值永远都不会超过1,因为每当j=1,遇到continue outer语句就结束了outer标签控制循环的当此循环,直接开始下一次循环,这时候i从i+1开始,j又将从0开始。

    展开全文
  • arm中断处理流程

    2020-12-21 03:07:02
    在接收到中断请求以后,ARM处理器内核会自动执行以上步,程序计数器PC总是跳转到相应的固定地址。从异常中断处理程序中返回包括下面两基本操作:1)恢复被屏蔽的程序的处理器状态;2)返回到发生异常中断的指令的...
  • Linux中断子系统()之中断申请注册 备注:   1. Kernel版本:5.4 ...  中断的处理主要有以下几功能模块:硬件中断号到Linux irq中断号的映射,并创建好irq_desc中断描述符;中断注册时,先获取设备的
  • GIC驱动分析2.GIC驱动流程分析第二部分 device node转化为platform_device第三部分:platform_device注册添加第部分 GPIO控制器驱动第五部分 引用GPIO中断的节点的解析第六部分 GPIO中断处理流程 本文以AM5728 ...
  • fpga中断流程梳理

    2021-06-20 13:43:50
    中断分为中断系统和中断源系统,因此两系统都需要一定的配置。并且需要把中断源系统挂载到中断系统上去。 pl向ps发出中断请求 1.获取配置和初始化中断,此时初始化的是arm cpu的中断系统SGI,然后需要注册中断处理...
  • GIC驱动程序对中断的处理流程1. 一级中断控制器处理流程2. 多级中断控制器处理流程 参考资料: linux kernel的中断子系统之(七):GIC代码分析 使用逐步演进的方法才能形象地理解。 1. 一级中断控制器处理流程 ...
  • 如果CPU处于开中断状态,系统就会中止正在运行的当前任务,而按中断向量的指向去运行中断服务子程序,当中断服务子程序运行完成后,系统会根据具体情况返回到被中止的任务继续运行,或转向另一个中断优先级别更高的...
  • 中断系统8.1 中断的基本概念8.1.1 中断概念的引入及描述中断方式示意(以输入中断为例)**中断**的定义8.1.2 中断源及中断分类中断的分类8.1.3 中断...处理过程中断向量的引导作用中断服务子程序的结构8.2 多级中断管理1....
  • 两类中断控制器处理流程_链式和层级1. 下级中断控制器的类别1.1 链式中断控制器(chained)1.2 层级中断控制器(hierarchy)2. 链式中断控制器的处理流程3. 层级中断控制器的处理流程4. 处理流程对比 参考资料: linux...
  • 中断向量表

    千次阅读 2021-01-21 13:34:06
    中断向量表(interrupt vector table,IVT)是中断源的识别标志,可用来形成相应的中断服务程序的入口地址或存放中断服务程序的首地址称为中断向量。在Pc/AT中由硬件产生的中断标识码被称为中断类型号(当然,中断类...
  • 目录一、中断的介绍1.1 单片机的中断1.2 STM32的中断1.2.1 中断地址1.2.2 中断优先级1.2.3 中断使能1.3 中断的过程二、利用STM32CubeMX生成HAL库代码,并实现LED的控制参考文献 一、中断的介绍 1.1 单片机的中断 ...
  • 在单片机程序设计中,设置一好的时钟中断,将能使一CPU发挥两CPU的功效,大大方便和简化程序的编制,提高系统的效率与可操作性。那么你对时钟中断了解多少呢?以下是由学习啦小编整理关于什么是时钟中断的内容...
  • 按下一代表字符的键,怎么变成平常使用的ASCII码的? 看完本文,相信你就能了解键盘的本质,知晓这些问题答案。 一、相关介绍 键盘编码器 键盘编码器(i8048),是键盘里的芯片,主要用来监控是否有键按下,弹起,...
  • 1、中断允许寄存器IE 2、中断优先级寄存器IP 3、定时器/计数器工作方式寄存器TMOD 4、定时器/计数器控制寄存器TCON 5、数码管和流水灯在中断中的应用 6、24小时制钟表
  • 微型计算机原理及应用学习笔记 8086/8088的中断编辑整理:贵州自考网 发表时间:2013-12-05 【大 中 小】8086/8088有一简单而灵活的中断系统,每个中断都有一个中断类型码(Type Code),以供CPU进行识别,8086/...
  • ARM中断处理过程

    2021-05-16 14:26:09
    以s3c2440ARM9核为例:一:s3c2440 ARM处理器特性:1、S3C2440支持60个中断源,含子中断源;2、ARM9采用五级流水线方式;3、支持外部中断和内部中断;二、s3c2440 支持的寄存器:2.1 外部中断寄存器24外部中断占用...
  • } } } /* USER CODE END 1 */ 设一全局变量,每进一次中断+1,因为1ms进入一次中断,所以当Tim_cnt=500的时候(即0.5s)写入我们需要运行的代码(不要忘记清0) 编译下载时需要选择相对应的下载器,勾选以下 ...
  • 浏览文章用51单片机中断编写的4x4键盘程序作者:未知来源:山涧一溪流点击数:…更新时间:2014年06月22日 【字体:大 中 小】应用查询扫描编写键盘程序,由于要给按键去抖动,程序变得比较复杂和冗长(详见2013年9月29...
  • 在proteus中绘制单片机和可编程中断控制器8259实现通过4按键触发中断作为8259的中断源输入,来控制单片机P3.3~P3.5的状态反转,数码管计数器的值加1,直到显示数字9,重新回0计数。
  • 之前我们完成了关于通过查询的方式获取按键键值的驱动程序,可以参考:嵌入式Linux开发——裸板程序之中断控制器。虽然读取键值没有什么问题,但是测试程序占用CPU过高,一直在不断的查询,资源消耗过大,这问题...
  • 简述CPU中断响应过程的九大步骤

    千次阅读 2020-12-19 13:28:25
    CPU响应中断:就是CPU要去执行相应的中断服务程序,其响应过程是CPU将现在执行程序的指令地址压入堆栈,跳转到中断服务程序入口地址,中断服务程序的入口地址就是中断向量,这个中断向量用216位寄存器存放。...
  • 中断方式中,外设满足传输条件后向处理器发送中断请求信号,然后处理器调用中断服务程序,进而提高了处理器的效率。现在,我们正式地认识一下中断中断是指微处理器在正常执行程序的过程中,当出现某些意外情况或...
  • 原标题:GNU ARM汇编()中断汇编之非嵌套中断处理在写这篇blog之前,不得不感慨一句:纸上得来终觉浅,绝知此事要躬行.作为EE出身的,虽然好久好久没用汇编写 的中断了,但自我感觉对中断的理解还是比较深入的,本以为在 ...
  • 6. ARM中断处理过程

    2020-12-23 01:30:09
    具体整个处理过程分成三步骤来描述:1、第二章描述了中断处理的准备过程2、第三章描述了当发生中的时候,ARM硬件的行为3、第章描述了ARM的中断进入过程4、第五章描述了ARM的中断退出过程本文涉及的代码来自3.14...
  • 绿化大师用着一直很稳定,但新版本4.0被顺网收购了,到时不但广告满天飞还会让你收费...服务器配置主板:Intel S1400FP4 网卡CPU:Intel XEON 至强E5-2420 1.9GHz硬盘:intel s3510 240G两块 S4610一块 intel 535...
  • F28335中断系统

    2021-04-09 19:34:14
    中断:是当CPU执行原来程序时,由于发生某种随机的事件(内部或外部),引起CPU暂时中断正在运行程序,转去执行一段特殊的服务程序(中断服务子程序或者中断处理程序),当执行完特殊的服务程序,CPU则返回继续执行原来...
  • 中断处理

    2021-05-17 23:52:13
    作者:smcdef 发布于:2018-1-1 17:03分类:中断子系统1) 设备唤醒cpu之后是立即跳转...如果不是,那中断服务函数做什么准备呢?而你注册的中断handle又会在什么时候才开始执行呢?3) 假如register_thread_irq方式注...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 86,126
精华内容 34,450
热门标签
关键字:

中断服务的四个流程