晶心科技線上技術研討會 AndesCore 便捷的全 C 嵌入式编程 晶心科技市場及技術服務部毛礼杰軟件經理 WWW.ANDESTECH.COM
大纲 系统初始化介绍 异常和中断说明 全 C 语法例子说明 总结 2
CPU 相关特性 1: 中断向量表 系统初始化 (1) 2: 系统寄存器 通常需要用 assembly( 汇编 / 组合 ) 语言来操作 AndesCore 全 C 嵌入式编程 C 扩展语法 用于 Exception/Interrupt 处理 Intrinsic function 用于系统寄存器设置等 适用于 Non-OS 系统 3
系统初始化 (2) 系统初始化 1: 中断向量表 2: 系统寄存器 3:memory 的初始化 4
汇编初始化 (1) 中断向量表 5
汇编初始化 (2) 系统寄存器 memory 初始化 其它初始化 6
ISR 入口前期汇编部分 汇编初始化 (3) 7
汇编与全 C 嵌入式编程系统初始化对比 Assemble crt0.s _start bal init Replacement Andes 全 C 嵌入式编程 void NDS32ATTR_RESET() { _nds32_init_mem() _cpu_init() _c_init() _soc_init() bal main } Main() 8
向量表 : 异常和中断 NDS32ATTR_RESET NDS32ATTR_EXCEPT NDS32ATTR_ISR 10
Include head file : nds32_isr.h Project Linker Setting Link libnds32_isr.a AndeSight Project 设定 11
中断向量表的设置 (1) +ISR at SaG 关于 SaG 语法可以参考技术文档 :Andes 的分散聚合 (SAG) 机制 http://www.andestech.com/cn/news-events/technicalarticle/2014/andes20141008.pdf 12
Link Script File 中断向量表的设置 (2) 13
NDSATTR_RESET(1) void NDS32ATTR_RESET( <option_list> ) reset_handler(void) <option_list> contains zero or more of the following separated by ; vectors=xxx nmi_func=yyy warm_func=zzz 14
NDSATTR_RESET(2) Example void NDS32ATTR_RESET("vectors=32;nmi_func=nmi_han dler;warm_func=warm_handler") reset_handler(void) { _nds32_init_mem(); cpu_init(); c_init(); soc_init(); main(); } 15
区分 NMI 和 Warm_Reset Cold Reset, NMI 和 Warm Reset 共用 vector 0 用 ir6 ETYPE 区分 系统根据 ir6 ETYPE 自动跳转到 nmi_fun 或者 warm_fun 16
_nds32_init_mem() 内存初始化函数 系统一上电或者是复位, 通常 memory 是不可用的, 在函数使用到 memory 之前准备好 memory 空间 系统 reset 后最先被呼叫 必须是个 leaf function, 因为 leaf function 可以做到不 push stack, 即不使用还未准备好的 memory 17
Intrinsic Function(1) AndesCore Intrinsic Function 和 CPU 紧密相关 用于设置系统寄存器,cache 操作等 通常对应于一条或几条机器指令, 以函数的形式来使用 类似于 inline assembly, 但避免了 inline assembly 使用上的较复杂语法 18
Intrinsic Function(2) AndesCore intrinsic function 例子 19
Intrinsic Function(3) _cpu_init() 函数使用 intrinsic function 20
NDS32ATTR_EXCEPT(1) ID=1 ID=2 21
NDS32ATTR_EXCEPT(2) void NDS32ATTR_EXCEPT ( id=xxx[;save_caller_regs;<is_nested>] ) excpt_hdlr(int vid) id=xxx, id should be 1 to 8 void NDS32ATTR_EXCEPT("not_nested;id=8") syscall_isr() { printf( syscall except ); return; } 22
NDS32ATTR_ISR(1) void NDS32ATTR_ISR ( id=xxx[;save_caller_regs;<is_nested>] ) intr_hdlr(int vid) id=xxx,id should be 0 to 63 <save_reg> <is_nested> 23
NDS32ATTR_ISR(2) Example void NDS32ATTR_ISR("not_nested;id=0,1") HW01_ISR(int vid) { printf( hw0,1 interrupt isr ); return; } ID=0 ID=1 24
<save_reg> (1) 两种 :save_caller_regs 或者 save_all_regs. (Default: save_caller_regs) save_caller_regs 保存 caller 寄存器, 通常 ISR 都是采用这种 int foo() { bar(); } foo(): caller bar(): callee save_all_regs 保存所有寄存器, 这种方式用于上下文切换 (context switch) 25
<save_reg> (2) save_all_regs(v3m toolchain) Entry the interrupt End of the interrupt 26
<save_reg> (3) save_caller_regs What s caller? Entry the interrupt End of the interrupt 27
四种模式 : nested : 可被中断嵌套. <is_nested> (1) not_nested : 不可被中断嵌套. ready_nested : 进入中断后手动打开 GIE 后可被中断嵌套, 通常用于完成一小段紧急处理后再打开 GIE 启用中断嵌套 critical : 用于紧急处理, 通常很简短, 不可被嵌套, 而且 ISR 须要是 leaf 函数 28
<is_nested> (2) ir0(psw) Processor Status Word Register GIE(Global Interrupt Enable) 0:interrupt disable 1:interrupt enable INTL(Interruption Stack Level) 0:No interruption 1:Interruption stack level 1 2:Interruption stack level 2 29
<is_nested> (3) Nested(GIE 启用, INTL 减 1) mfsr $r3,$psw subi333 $r3,$r3,#1 mtsr $r3,$psw Ready_neseted(INTL 减 1) mfsr $r3,$psw subi333 $r3,$r3,#2 mtsr $r3,$psw 30
<is_nested> (4) No_nested(PSW 保持不变 ) 做保存寄存器相关操作 Critical 直接跳转到 ISR 寄存器也不保存 31
<is_nested> (5) <is_nested> GIE Enable INTL-1 SAVE_REG Nested YES YES YES Ready_Nested NO YES YES No_Nested NO NO YES Critical NO NO NO 32
参考示例代码 Installation AndeSight folder\demo\startup\demo-intc-ext.tgz 33
总结 AndesCore 全 C 嵌入式编程 减轻学习新指令的开销 减少开发时间 便于系统调试和维护 34
Thank You! WWW.ANDESTECH.COM