Try   HackMD

作業系統工程-Interrupt

Table Of Content

tags: 作業系統工程 Operating System Programming note, 110-1, 2021


RT-Thread 中斷管理 function

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

RT-Thread include .h file

Interrupt handler definition

typedef void (*rt_isr_handler_t)(int vector, void *param); struct rt_irq_desc { rt_isr_handler_t handler; void *param; #ifdef RT_USING_INTERRUPT_INFO char name[RT_NAME_MAX]; rt_uint32_t counter; #endif };

Interrupt interfaces

void rt_hw_interrupt_init(void); void rt_hw_interrupt_mask(int vector); void rt_hw_interrupt_umask(int vector); rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, void *param, const char *name);
  • Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →
    以 ARM Cortex-a 介紹相關 function 內的 Coding

Interrupt .h file

#define __INTERRUPT_H__

#include <rthw.h>
#include <board.h>

#define INT_IRQ     0x00
#define INT_FIQ     0x01

void rt_hw_vector_init(void);

void rt_hw_interrupt_control(int vector, int priority, int route);

void rt_hw_interrupt_init(void);
void rt_hw_interrupt_mask(int vector);
void rt_hw_interrupt_umask(int vector);

int rt_hw_interrupt_get_irq(void);
void rt_hw_interrupt_ack(int vector);

rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
        void *param, const char *name);

#endif

稍微參考其中幾個 function 的寫法

void rt_hw_interrupt_init();

  • 初始化
  1. 中斷向量表
void rt_hw_vector_init(void) { rt_cpu_vector_set_base((unsigned int)&system_vectors); }
  1. 例外處理表
struct rt_irq_desc isr_table[MAX_HANDLERS]; void rt_hw_interrupt_init(void) { rt_uint32_t gic_cpu_base; rt_uint32_t gic_dist_base; rt_uint32_t gic_irq_start; rt_hw_vector_init();/* 1. initialize vector table */ rt_memset(isr_table, 0x00, sizeof(isr_table));/* 2. initialize exceptions table */ /* initialize ARM GIC */ gic_dist_base = platform_get_gic_dist_base(); gic_cpu_base = platform_get_gic_cpu_base(); gic_irq_start = GIC_IRQ_START; arm_gic_dist_init(0, gic_dist_base, gic_irq_start); arm_gic_cpu_init(0, gic_cpu_base); }

void rt_hw_interrupt_mask();

void rt_hw_interrupt_mask(int vector) { arm_gic_mask(0, vector); }
  • Cortex-a 中 gic.c 的實作方式

#define GIC_DIST_ENABLE_CLEAR(hw_base, n) __REG32((hw_base) + 0x180 + ((n)/32) * 4) void arm_gic_mask(rt_uint32_t index, int irq) { rt_uint32_t mask = 1 << (irq % 32); RT_ASSERT(index < ARM_GIC_MAX_NR); irq = irq - _gic_table[index].offset; RT_ASSERT(irq >= 0); GIC_DIST_ENABLE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; // 差別在這行! }

void rt_hw_interrupt_umask();

void rt_hw_interrupt_umask(int vector) { arm_gic_umask(0, vector); }
  • Cortex-a 中 gic.c 的實作方式

#define GIC_DIST_ENABLE_SET(hw_base, n) __REG32((hw_base) + 0x100 + ((n)/32) * 4) void arm_gic_umask(rt_uint32_t index, int irq) { rt_uint32_t mask = 1 << (irq % 32); RT_ASSERT(index < ARM_GIC_MAX_NR); irq = irq - _gic_table[index].offset; RT_ASSERT(irq >= 0); GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask; // 差別在這行! }

rt_isr_handler_t rt_hw_interrupt_install();

rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, void *param, const char *name) { rt_isr_handler_t old_handler = RT_NULL; if (vector < MAX_HANDLERS) { old_handler = isr_table[vector].handler; if (handler != RT_NULL) { #ifdef RT_USING_INTERRUPT_INFO rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX); #endif /* RT_USING_INTERRUPT_INFO */ isr_table[vector].handler = handler; isr_table[vector].param = param; } } return old_handler; }