2016-11-22 21 views
5

Tôi cố gắng để thực hiện các giả sau đây trên một bộ điều khiển vỏ não-m3, (STM32L151 nói riêng)Thay đổi mức độ ưu tiên của trình xử lý ngắt đang chạy?

void SysTick_Handler() { 
    do_high_priority_periodic_tasks(); // not to be interrupted 
    lower_interrupt_priority(); 
    do_low_priority_periodic_tasks(); // these may be interrupted 
} 

Nói cách khác, chạy phần đầu tiên với mức ưu tiên 0, sau đó bằng cách nào đó làm giảm ưu tiên ngắt hiện tại để 15, để phần còn lại có thể được preempted bởi phần cứng khác ngắt.

Một ý tưởng là di chuyển do_low_priority_periodic_tasks(); vào trình xử lý gián đoạn riêng biệt và gọi trình xử lý này qua NVIC_SetPendingIRQ() đặt bit đang chờ xử lý trong thanh ghi NVIC->ISPR[]. Bằng cách này, ngắt khác sẽ ngay lập tức theo sau SysTick, trừ khi có bất kỳ điều gì có mức độ ưu tiên từ 0 đến 14 đang chờ xử lý.

#define LOWPRIO_IRQn 55 
void IRQ55_Handler() { 
    do_low_priority_periodic_tasks(); // these may be interrupted 
} 

void SysTick_Handler() { 
    do_high_priority_periodic_tasks(); // not to be interrupted 
    NVIC_SetPendingIRQ(LOWPRIO_IRQ); 
} 

void main() { 
    HAL_Init(); 
    HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); 
    HAL_NVIC_SetPriority(LOWPRIO_IRQn, 15, 0); 
    HAL_NVIC_EnableIRQ(LOWPRIO_IRQn); 
    while(1) { 
     /* main loop */ 
    } 
} 

Tôi đã chọn IRQ 55 vì nó không bị chiếm trên bộ điều khiển của tôi, nó sẽ là bộ xử lý ngắt AES trên STM32L162, nhưng tôi hơi lo lắng ở đó. Tôi có nên chọn một IRQ khác thay vào đó, có lẽ một kênh DMA không sử dụng bị gián đoạn? Có an toàn để sử dụng ngắt 57-67, được xác định trong lõi Cortex-M3, nhưng không phải trên dòng STM32L? Có cách nào tốt hơn để làm điều đó không?

Trả lời

4

Có an toàn khi sử dụng ngắt 57-67, được xác định trong lõi Cortex-M3 chứ không phải trên dòng STM32L?

No. NVIC của bạn có thể không thực sự triển khai chúng.

Nhưng PendSV được chính xác thực hiện cho nhiệm vụ này:

void SysTick_Handler() { 
    do_high_priority_periodic_tasks(); // not to be interrupted 
    // Set the PENDSVSET to trigger a PendSV exception 
    SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; 
} 

void PendSV_Handler() { 
    do_low_priority_periodic_tasks(); // these may be interrupted 
} 

Xem thêm answer này về PendSV.

+0

Đó chính xác là những gì tôi đang tìm kiếm, cảm ơn – berendi

+0

Bạn có thể thay đổi mức độ ưu tiên rất tốt. 'PendSV thường được sử dụng cho RTOS và không sử dụng trình xử lý ngắt người dùng, hãy tách nó ra sẽ không có sẵn cho nhiều trình xử lý. Điều đó hoàn toàn không liên quan đến việc sử dụng các ngắt không thực hiện. – Olaf

Các vấn đề liên quan