找回密码
 立即注册
查看: 743|回复: 12

一种USER_ISP和USER_APP共用中断方法

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:328
  • 最近打卡:2025-10-15 08:50:20
已绑定手机

85

主题

3256

回帖

7196

积分

荣誉版主

无情的代码机器

积分
7196
发表于 2025-4-21 10:51:19 | 显示全部楼层 |阅读模式

遇到坛友提问如何在USER_ISP和USER_APP共用中断
这里借助xdata,放置标识区分程序运行环境以及APP函数指针,在USER_ISP中断里判断跳转,实测可行。



需要在USER_ISP工程isr.asm里屏蔽共用的中断。
如需扩展多个函数指针,注意结构体在xdata中内存布局。


在官网“8系列UART在线升级”基础上更改:
STC-official-user-UART-ISP-bootloader-demo-STC8H8K64U-series-isr.zip (870.07 KB, 下载次数: 69)

1 喜欢他/她就送朵鲜花吧,赠人玫瑰,手有余香!
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

3

主题

1880

回帖

608

积分

等待验证会员

积分
608
发表于 2025-4-21 10:53:00 | 显示全部楼层
在嵌入式系统开发中,USERISP(用户在线编程)和USERAPP(用户应用程序)共用中断是一个常见的需求。为了实现这一功能,可以采用一种基于xdata的标识区分方法,并通过函数指针进行跳转。以下是一个详细的实现方案。

1. 基本思路

通过在xdata中放置标识符来区分当前运行的是USERISP还是USERAPP,并在中断服务例程(ISR)中根据标识符进行相应的跳转。具体步骤如下:

1. 定义标识符和函数指针:在xdata中定义一个结构体,包含标识符和函数指针。
2. 初始化标识符:在USERISP和USERAPP的初始化代码中设置相应的标识符。
3. 修改中断服务例程:在ISR中根据标识符跳转到相应的处理函数。

2. 实现步骤

2.1 定义结构体

首先,在xdata中定义一个结构体,用于存储标识符和函数指针。
  1. c
  2. typedef struct {
  3.     uint8t ispflag;  // 标识符,0表示APP,1表示ISP
  4.     void (appisr)(void);  // APP中断处理函数指针
  5. } ISRStruct;
  6. xdata ISRStruct isrinfo;
复制代码

2.2 初始化标识符

在USERISP和USERAPP的初始化代码中,分别设置标识符和函数指针。

USERISP初始化代码:
  1. c
  2. isrinfo.ispflag = 1;  // 设置为ISP模式
  3. isrinfo.appisr = NULL;  // ISP模式下不需要APP中断处理函数
复制代码

USERAPP初始化代码:
  1. c
  2. isrinfo.ispflag = 0;  // 设置为APP模式
  3. isrinfo.appisr = &appisrhandler;  // 设置APP中断处理函数
复制代码

2.3 修改中断服务例程

在ISR中根据标识符进行跳转。
  1. c
  2. void commonisr(void) interrupt(INTERRUPTNUMBER) {
  3.     if (isrinfo.ispflag) {
  4.         // ISP模式下的处理逻辑
  5.         ispisrhandler();
  6.     } else {
  7.         // APP模式下的处理逻辑
  8.         if (isrinfo.appisr != NULL) {
  9.             isrinfo.appisr();
  10.         }
  11.     }
  12. }
复制代码

2.4 屏蔽共用的中断

在USERISP工程的israsm文件中,屏蔽共用的中断,以避免冲突。
  1. assembly
  2. ; 在israsm文件中屏蔽共用的中断
  3. ; 例如,屏蔽UART中断
  4. CLR EA  ; 关闭全局中断
  5. CLR ES  ; 关闭串口中断
复制代码

3. 扩展多个函数指针

如果需要扩展多个函数指针,可以在结构体中增加相应的字段,并注意结构体在xdata中的内存布局。
  1. c
  2. typedef struct {
  3.     uint8t ispflag;  // 标识符,0表示APP,1表示ISP
  4.     void (appisr1)(void);  // APP中断处理函数指针1
  5.     void (appisr2)(void);  // APP中断处理函数指针2
  6. } ISRStruct;
  7. xdata ISRStruct isrinfo;
复制代码

在ISR中根据需要进行跳转。
  1. c
  2. void commonisr(void) interrupt(INTERRUPTNUMBER) {
  3.     if (isrinfo.ispflag) {
  4.         // ISP模式下的处理逻辑
  5.         ispisrhandler();
  6.     } else {
  7.         // APP模式下的处理逻辑
  8.         if (isrinfo.appisr1 != NULL) {
  9.             isrinfo.appisr1();
  10.         }
  11.         if (isrinfo.appisr2 != NULL) {
  12.             isrinfo.appisr2();
  13.         }
  14.     }
  15. }
复制代码

4. 总结

通过上述方法,可以实现USERISP和USERAPP共用中断的功能。关键在于使用xdata中的标识符和函数指针进行跳转,并在ISR中根据标识符执行相应的处理逻辑。这种方法不仅简单高效,而且易于扩展,适用于多种嵌入式系统开发场景。

5. 注意事项
内存布局:在扩展多个函数指针时,需注意结构体在xdata中的内存布局,确保各字段正确对齐。
中断屏蔽:在USERISP工程中,务必屏蔽共用的中断,以避免冲突。
测试验证:在实际应用中,需进行充分的测试验证,确保功能稳定可靠。

通过以上步骤,开发者可以有效地实现USERISP和USERAPP共用中断的功能,提升系统的灵活性和可维护性。

[本文内容由国芯人工智能辅助生成,仅供参考]

点评

真·人工智能  发表于 2025-4-21 11:04
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:328
  • 最近打卡:2025-10-15 08:50:20
已绑定手机

85

主题

3256

回帖

7196

积分

荣誉版主

无情的代码机器

积分
7196
发表于 2025-4-22 23:54:16 | 显示全部楼层

注意:
32G8K64 是6k xdata + 2k edata。ISP&APP公共变量需要挪到xdata 6k之前。
32G8K64 是6k xdata + 2k edata。ISP&APP公共变量需要挪到
xdata 6k之前。
32G8K64 是6k xdata + 2k edata。ISP&APP公共变量需要挪到
xdata 6k之前。

截图202504222352592177.jpg
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-09-30 09:11:37
已绑定手机

0

主题

6

回帖

32

积分

新手上路

积分
32
发表于 2025-9-22 10:50:40 | 显示全部楼层
  1. typedef struct {
  2.         u8 isAppRunning;
  3.         void (*app_tm0_isr)(void);
  4. void (*app_uart1_isr)(void);
  5.         void (*app_uart2_isr)(void);
  6. }UserAppConfig;
  7. extern UserAppConfig xdata appConfig;
  8. volatile uint32_t xdata DfuFlag _at_ 0x0BFC;
  9. UserAppConfig xdata appConfig _at_(0x0BE0);
  10. //-----------------------------------------------------------------------------
  11. void UART2_ISR_Handler() interrupt UART2_VECTOR
  12. {
  13.         if(appConfig.isAppRunning && appConfig.app_uart2_isr != NULL)
  14. {
  15.                 ((void (code *)())(appConfig.app_uart2_isr))();
  16.         }
  17. else
  18. {
  19.   u8 tmp=0;
  20.   if (S2CON & 0x02)    //发送
  21.   {
  22.    S2CON &= ~0x02;     //清中断标志
  23.    Uart2TxFlag=0;
  24.   }
  25.   if (S2CON & 0x01)
  26.   {
  27.    S2CON &= ~0x01;     //清中断标志
  28.    tmp=S2BUF;        
  29.    uart_receive_input(tmp);                          
  30.   }
  31. }
  32. }
  33. //-----------------------------------------------------------------------------
  34. LDR_SIZE    EQU     4000H
  35. MAPISR      MACRO   ADDR
  36.             CSEG    AT  ADDR
  37.             LJMP    LDR_SIZE + $
  38.             ENDM
  39.             MAPISR  0003H
  40.            ;MAPISR  000BH
  41.             MAPISR  0013H
  42.             MAPISR  001BH
  43.             ;MAPISR  0023H
  44.             MAPISR  002BH
  45.             MAPISR  0033H
  46.             MAPISR  003BH
  47.            ;MAPISR  0043H
  48.             MAPISR  004BH
  49.             MAPISR  0053H
  50.             MAPISR  005BH
  51.             MAPISR  0063H
复制代码
  1. APP中串口中断2代码:
  2. //-----------------------------------------------------------------------------
  3. //void UART2_Isr() interrupt 8
  4. void app_uart2_isr(void)
  5. {
  6. u8 tmp=0;
  7. if (S2CON & 0x02)//发送
  8. {
  9.   S2CON &= ~0x02;                         //清中断标志
  10.   Uart2TxFlag=0;
  11. }
  12. if (S2CON & 0x01)
  13. {
  14.   S2CON &= ~0x01;                         //清中断标志
  15.   tmp=S2BUF;       
  16.   uart_receive_input(tmp);                          
  17. }
  18. }
  19. //-----------------------------------------------------------------------------
复制代码


您好,请教下现用STC8H3K64S2 按例程配置的共用中断的方式实现IAP升级,程序能跑起来,串口2是接的WIFI模组,数据量大的情况下,就出现异常重启复位,请问这是什么原因呢?
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-09-30 09:11:37
已绑定手机

0

主题

6

回帖

32

积分

新手上路

积分
32
发表于 2025-9-22 11:05:45 | 显示全部楼层
共用的三个中断也屏蔽了,程序从ISP跳到APP也能跑,取消ISP功能代码,单独使用APP代码都正常,还没找到是哪的问题

点评

什么问题?需要帮助吗?可以描述下问题,上传下完整工程  详情 回复 发表于 2025-9-22 11:33
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:328
  • 最近打卡:2025-10-15 08:50:20
已绑定手机

85

主题

3256

回帖

7196

积分

荣誉版主

无情的代码机器

积分
7196
发表于 2025-9-22 11:33:52 | 显示全部楼层
jieke*** 发表于 2025-9-22 11:05
共用的三个中断也屏蔽了,程序从ISP跳到APP也能跑,取消ISP功能代码,单独使用APP代码都正常,还没找到是哪 ...

什么问题?需要帮助吗?可以描述下问题,上传下完整工程
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-09-30 09:11:37
已绑定手机

0

主题

6

回帖

32

积分

新手上路

积分
32
发表于 2025-9-22 13:22:53 | 显示全部楼层
erci*** 发表于 2025-9-22 11:33
什么问题?需要帮助吗?可以描述下问题,上传下完整工程

在跑APP代码时,串口2中断数据量大时会异常重启的现象,上有贴共用中断的部分代码

点评

没有显示,可以重新打包上传完整可复现问题工程 [attachimg]115830[/attachimg]  详情 回复 发表于 2025-9-22 13:56
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:328
  • 最近打卡:2025-10-15 08:50:20
已绑定手机

85

主题

3256

回帖

7196

积分

荣誉版主

无情的代码机器

积分
7196
发表于 2025-9-22 13:56:11 | 显示全部楼层
jieke*** 发表于 2025-9-22 13:22
在跑APP代码时,串口2中断数据量大时会异常重启的现象,上有贴共用中断的部分代码 ...

没有显示,可以重新打包上传完整可复现问题工程
截图202509221356068641.jpg
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-09-30 09:11:37
已绑定手机

0

主题

6

回帖

32

积分

新手上路

积分
32
发表于 2025-9-27 14:56:28 | 显示全部楼层
20250926-NoRF.rar (1.92 MB, 下载次数: 3) 您好,工程已上传,单独共用串口2中断还是会出现复位的现象,在跑APP时程序很卡顿,取消IAP中的中断共享后就正常,因采用WIFI模组接收,需配合硬件才好复现此问题,试过IAP中采用绝对地址跳转到APP中还是一样的情况,先帮忙看下程序IAP与APP中断共享这块配置是否有问题,感谢!
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-09-30 09:11:37
已绑定手机

0

主题

6

回帖

32

积分

新手上路

积分
32
发表于 2025-9-27 15:00:39 | 显示全部楼层
erci*** 发表于 2025-9-22 13:56
没有显示,可以重新打包上传完整可复现问题工程

您好,工程已上传,麻烦帮忙看看配置是否有问题,主要是串口2数据量大时容易复位重启,像是堆栈溢出程序跑飞了

点评

if(tSwitch3.countdw=0) 看到一处语法错误,APP跳转部分只要能跳转过去正常进回调配置就没啥大问题, 建议分步调试,APP代码简化到和串口工具调试串口收发,屏蔽其它逻辑,发什么回什么,看是否容易复现。  详情 回复 发表于 2025-9-27 20:44
回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-10-16 05:42 , Processed in 0.141226 second(s), 106 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表