GD32VF103CBT6コントローラーの構造について引き続き詳しく説明します。次に、高レベルのコードの制御下で機能するように割り込みを処理する方法を見てみましょう。
最初の部分はここにあります
7.UART接続
再帰の問題を選択するときに、複雑なアルゴリズムをデバッグするには3つのLEDでは不十分であるという問題に遭遇しました。それでは、screenのような端末プログラムがプレーンテキストを使用してコントローラーとフックして通信できる本格的なデバッグインターフェイスを追加しましょう。これを行うには、ファームウェアに使用されているのと同じUSART0を使用します。
用語に関連する小さな逸脱:USART(ユニバーサル同期-非同期受信機-送信機)は、その名前が示すように、同期モードと非同期モードの両方で機能します。そして他の多くの人たちですが、彼らはまだ私たちにとって興味がありません。実際には、同期モードで動作するのを見たことがありません。したがって、USARTとともに、非同期モードを意味するUART指定を使用します。
ポートと同様に、最初のステップはこのモジュールを有効にすることです。ドキュメントを調べて、対応するRCUビットを確認し、RCU_APB2EN_USART0ENの14番目のビットを確認します。 STMに続くGD32VF103の次の機能は、出力ピンの動作モードを通常のGPIOから値GPIO_APP50 = 0b1011によってアクティブ化される代替機能に切り替える必要があることです。そして出力のみ:入力レッグは通常のGPIO_HIZのままです。そうです、RCUでは、代替機能が機能する可能性も有効にする必要があります。これはビット0、別名RCU_APB2EN_AFENによって行われます。
ただし、UARTの設定自体は難しくありません。USART0_CTL0レジスタで、その操作を有効にし(USART_CTL0_UEN)、送信機(USART_CTL0_TEN)と受信機(USART_CTL0_REN)をオンにしてから、USART0_BAUDレジスタの交換レートをクロック分周器として設定します。より正確には、クロック周波数ではなく、APB2バス周波数のみですが、クロッキングがわかるまで、すべてのバスの周波数は同じで、8MHzに等しくなります。
la t0, USART0_BASE li t1, 8000000 / 9600 sw t1, USART_BAUD_OFFSET(t0) li t1, USART_CTL0_UEN | USART_CTL0_REN | USART_CTL0_TEN sw t1, USART_CTL0_OFFSET(t0) la t0, USART0_BASE li t1, 'S' sb t1, USART_DATA_OFFSET(t0)
, … , .
USART0_DATA.
, ,
$ screen /dev/ttyUSB0 9600
'S' . screen, ctrl+a, k, y.
8.
. UART : . , . , UART : 9600 , 115200. 8 , 108 , , . USART_STAT_TBE (Transmit data buffer empty) USART0_STAT.
:
void uart_puts(char *str){
while(str[0] != '\0'){
while(! (USART0_STAT & USART_STAT_TBE) ){}
USART0_DATA = str[0];
str++;
}
}
, , 14 .
, USART_STAT_RBNE (Read data buffer not empty), '\r' '\n' .
UART , , .
9.
, . , , . , ?
— , , . (polling) . , . UART , , — .
, , USB, . , , (-, ), . ?
— , . : , . , .
RISC-V : , , ( ), . , . : , , . , , . , , , . , , , . , , .
, , sp.
, . GD32VF103 eclic (Enhanced Core Local Interrupt Controller). , . , , , . : (NMI), (traps) (interrupts). , . ( breakpoint ecall ebreak), . , ( ) . UART`.
eclic . , . scrr () scrw (). , , mtvec. 26 , 6 — : 3 eclic, — , clic ( ?):
la t0, trap_entry andi t0, t0, ~(64-1) # 64 ori t0, t0, CSR_MTVEC_ECLIC csrw CSR_MTVEC, t0
, , , 64- . .align 6:
.align 6 trap_entry: push t0 push t1 push a0 la t0, GPIOB_OCTL lh t1, 0(t0) xori t1, t1, (1<<GLED) sh t1, 0(t0) la t0, USART0_BASE la t1, USART_CTL0_UEN | USART_CTL0_REN | USART_CTL0_TEN sw t1, USART_CTL0_OFFSET(t0) la t1, 'I' sw t1, USART_DATA_OFFSET(t0) la a0, 100000 call sleep pop a0 pop t1 pop t0 mret
UART`, . , - . , — . UART USART_CTL0_TBEIE, , . . 'I' . . , , - .
USART_CTL0_TBEIE USART0_CTL0, . eclic . :
# USART0 (eclic_int_ie[i] = 1) la t0, (ECLIC_ADDR_BASE + ECLIC_INT_IE_OFFSET + USART0_IRQn*4) la t1, 1 sb t1, 0(t0) # csrrs zero, CSR_MSTATUS, MSTATUS_MIE
. ECLIC_ADDR_BASE + ECLIC_INT_IP_OFFSET , . :
struct{
uint8_t clicintip; //interrupt pending
uint8_t clicintie; //interrupt enable
uint8_t clicintattr; //attributes
uint8_t clicintctl; //level and priority
}eclic_interrupt[ECLIC_NUM_INTERRUPTS];
- clicintip — . . .
- clicintie — . , clicintip . .
- clicintattr — . clicintip ( 0->1 1->0) . .
- clicintctl — . .
, 8-, sb. , - , . , , , , . , , .
USART0_IRQ 56- , clicintie, 1.
, USART_CTL0_TBEIE, . , , , .
UPD: : . , ? , — , ( ?), . ( RISC-V ) mscratchcsw. :
csrrw sp, mscratchcsw, sp # - csrrw sp, mscratchcsw, sp
10.
, , , . . , ecall. , . , , 16-, 32-. , . 32-. ra, mepc, 4 .
, . , . mcause, 31- , . 1, , 0 — . . 0-11 ( 31- 0) ( 1). :
0 — instruction address misaligned,
1 — instruction access fault,
2 — illegal instruction,
3 — breakpoint, ebreak
4 — load address misaligned,
5 — load address fault,
6 — store/AMO misaligned,
7 — store/AMO access fault,
8 — enviroment call from U-mode, ecall,
9 — ?
10 — ?
11 — Enviroment call from M-mode, ecall,
2, 3 11.
( 2) . , 0xFFFF'FFFF ( ).
ebreak ( 3) . 32-. , ebreak 2 . , .
ecall 11- , 8- . , , . .
( 0xFFFF'FFFF), ecall. .
. , eclic? mcause. . UART` . "" , . , :
.align 6 trap_entry: push t0 push t1 push a0 csrr a0, CSR_MCAUSE la t1, (1<<31) and t1, a0, t1 #t1 - interrupt / trap beqz t1, trap_exception #interrupt la t0, GPIOB_OCTL lh t1, 0(t0) xori t1, t1, (1<<GLED) sh t1, 0(t0) la t0, 0xFFF and a0, a0, t0 la t0, USART0_IRQn bne t0, a0, trap_end la t0, USART0_BASE la t1, USART_CTL0_UEN | USART_CTL0_REN | USART_CTL0_TEN sw t1, USART_CTL0_OFFSET(t0) la t1, 'I' sw t1, USART_DATA_OFFSET(t0) trap_end: la a0, 100000 call sleep pop a0 pop t1 pop t0 mret trap_exception: la t0, GPIOB_OCTL lh t1, 0(t0) xori t1, t1, (1<<RLED) sh t1, 0(t0) csrr t0, CSR_MEPC addi t0, t0, 4 csrw CSR_MEPC, t0 j trap_end
11.
: . , . mtvt2: 30 , 1- , (mtvt2 + mtvec) 1, . , 4- . :
la t0, irq_entry csrw CSR_MTVT2, t0 # 4 csrs CSR_MTVT2, 1
. , mcause:
align 2 irq_entry: push t0 push t1 push a0 csrr a0, CSR_MCAUSE la t0, 0xFFF and a0, a0, t0 la t0, USART0_IRQn bne t0, a0, irq_end la t0, USART0_BASE la t1, USART_CTL0_UEN | USART_CTL0_REN | USART_CTL0_TEN sw t1, USART_CTL0_OFFSET(t0) la t1, 'I' sw t1, USART_DATA_OFFSET(t0) la t0, GPIOB_OCTL lh t1, 0(t0) xori t1, t1, (1<<YLED) sh t1, 0(t0) la a0, 100000 call sleep irq_end: pop a0 pop t1 pop t0 mret
, .
12.
. . 64, 128, 256, 512, 1024, 2048, 4096, 8192 16384 . , : - (OR) . 86 , 4 , 344 . , — 512, .align 9. , , . . : . , . , 4 :
.text .section .init ... .align 9 vector_base: j _start .align 2 .word 0 .word 0 .word eclic_msip_handler ... .word RTC_IRQHandler ... .word SPI1_IRQHandler .word USART0_IRQHandler ... .align 2 .text .global _start _start: la sp, _stack_end ...
. . , UART
USART0_IRQHandler: push t0 push a0 la t0, USART0_BASE la a0, USART_CTL0_UEN | USART_CTL0_REN | USART_CTL0_TEN sw a0, USART_CTL0_OFFSET(t0) la a0, 'U' sw a0, USART_DATA_OFFSET(t0) la t0, GPIOB_OCTL lh a0, 0(t0) xori a0, a0, (1<<GLED) sh a0, 0(t0) la a0, 100000 call sleep pop a0 pop t0 mret
mtvt:
la t0, vector_base csrw CSR_MTVT, t0
clicintattr . : 1 2 :
0b00, 0b01 — , clicintip
0b10 — , 0 1
0b11 — , 1 0.
, EXTI, . .
0 - . 0 ( ) - , 1 — .
# (eclic_int_attr[i] = 1) la t0, (ECLIC_ADDR_BASE+ECLIC_INT_ATTR_OFFSET+USART0_IRQn*4) la t1, 1 sw t1, 0(t0)
- , UART .
- , .
la t0, nmi_entry csrs CSR_MNVEC, t0 li t0, (1<<9) csrs CSR_MMISC_CTL, t0
13.
, . . . , , . , startup.S, main.c. ` , UART' , , . -. , . pinmacro.h :
#define RLED B, 5, 1, GPIO_PP50
#define SBTN B, 0, 0, GPIO_HIZ
...
GPIO_config( RLED );
GPIO_config( SBTN );
GPO_ON( RLED );
if( GPI_ON( SBTN ) )GPIO_OFF( RLED);
main . argc argv. - return.
li a0, 0 li a1, 0 call main INF_LOOP: .weak UnhandledInterruptHandler UnhandledInterruptHandler: j INF_LOOP
, . , :
.weak IRQHandler IRQHandler: .weak NMIHandler NMIHandler: .weak TrapHandler TrapHandler: j UnhandledInterruptHandler
, . , . . UnhandledInterruptHandler .
.weak, , , (, , ...) - , , , , , "".
, , '. , , .start, , .
, ' . , . lib.
14.
, . , , . , lib/Firmware/RISCV/drivers/n200_func.c. eclic_set_vmode ( ) eclic_enable_interrupt ( ). - . , :
#define eclic_global_interrupt_enable() set_csr(mstatus, MSTATUS_MIE)
#define eclic_global_interrupt_disable() clear_csr(mstatus, MSTATUS_MIE)
n200_func.c makefile src. , eclic_init, ( !). , . , SystemCoreClock. , .
, : ( t0-t6), mret ret. ' , , :
__attribute__((interrupt)) void USART0_IRQHandler(void)
, , lib/interrupt_util.h . , .
, , main , — , . , , :
__attribute__((naked)) int main();
, , .
, .
RISC-V , AVR ARM . , , , , . : , — . , , .
USART_DATA( USART0 ) DMA , stm32. .
RISC-V ARM, , . RISC-V : - ( li, , , "Myriad sequences"). , .
GD32VF103 ? . . GigaDevice stm32f103, . , stm32l151. — , , stm32f103. , RISC-V — x86, ARM, RISC-V - .
https://habr.com/ru/post/516006/
https://www.youtube.com/watch?v=M0dEugoU8PM&list=PL6kSdcHYB3x4okfkIMYgVzmo3ll6a9dPZ
https://www.youtube.com/watch?v=LyQcTmNcSpY&list=PL6kSdcHYB3x6KOBxEP1YZAzR8hkMQoEva
ます。https: //doc.nucleisys.com/nuclei_spec/isa/eclic.html
http://www.gd32mcu.com/en/download/0?kw=GD32VF1