求助, CH32V307 的 SW_Handler 只执行了一次

刚刚购买了 307 的开发板.  做了一些尝试. 


下面的代码比较简单 ,  请大家看看为什么 SW_Handler 只执行一次 ?  

/********************************** (C) COPYRIGHT *******************************
* File Name          : main.c
* Author             : WCH
* Version            : V1.0.0
* Date               : 2021/06/06
* Description        : Main program body.
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/

/*
 *@Note
 串口打印调试例程:
 USART1_Tx(PA9)。
 本例程演示使用 USART1(PA9) 作打印调试口输出。

*/

#include "debug.h"

__IO uint32_t ST_Counter=0;

void SysTick_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));

void SysTick_Handler(void)
{
    SysTick->SR  = 0;
    ST_Counter ++;
}

__IO uint32_t SW_Counter=0;

void SW_Handler()
{
  SW_Counter++;
  SysTick->CTLR &= ~(1 << 31);
}


int gv=0;
void CpuLoopDelay(){
    for(int t=0;t<10300000;t++)
        gv+=123+t*gv;
}

int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

	SysTick->CTLR = 0x00000000;             //控制寄存器复位
    SysTick->SR = 0x00000000;               //状态寄存器复位
    SysTick->CNT = 0x00000000;              //计数器复位,设置初始值为0
    SysTick->CMP = SystemCoreClock / 8000;                   //给重加载寄存器赋值
    NVIC_SetPriority(SysTicK_IRQn, 15);     //设置SysTick中断优先级
    NVIC_EnableIRQ(SysTicK_IRQn);           //使能开启Systick中断
    NVIC_SetPriority(Software_IRQn, 0xf0);
    NVIC_EnableIRQ(Software_IRQn);
    SysTick->CTLR |= 0x0000000B;            //启动系统计数器STK(HCLK/8时基)


	USART_Printf_Init(115200);
	printf("SystemClk:%d\r\n",SystemCoreClock);

	printf("This is printf example\r\n");

	while(1)
    {
	    CpuLoopDelay();
	    printf("ST=%d , SW=%d , CTLR=0x%x \r\n",ST_Counter,SW_Counter,SysTick->CTLR);

        SysTick->CTLR |= (1 << 31) ;
	}
}

运行的结果如图

SysTick_Handler 正常,   SW_Handler 执行了一次后,  后面无法再触发了. 

riscv_test1.png

自己结贴吧. 


看了某些RTOS的实现, 都是在汇编里写的代码.  最后需要用 mret 返回. 


查了一下.  riscv 对中断返回有特定要求,  不能用ja ra返回. 


所以, 标记为 

__attribute__((interrupt("WCH-Interrupt-fast")));

便可.  否则返回方式不一致会导致堆栈混乱产生各种奇奇怪怪的现象. 



只有登录才能回复,可以选择微信账号登录