From: AceVest Date: Wed, 16 Oct 2019 05:25:11 +0000 (+0800) Subject: ... X-Git-Url: http://zhaoyanbai.com/repos/?a=commitdiff_plain;h=dbca21253f6384556f59d2744c76227d59ff54c3;p=acecode.git ... --- diff --git a/documents/RISC-V.md b/documents/RISC-V.md new file mode 100644 index 0000000..e689d52 --- /dev/null +++ b/documents/RISC-V.md @@ -0,0 +1,47 @@ +# RISC-V + +## Bumblebee的中断 + +### 1. CSR `mtvec`的功能 + +Bumblebe内核遵循的标准 RISC-V 特权架构文档版本为:“特权架构文档版本 1.10” (riscv-privileged-v1.10.pdf),在这个版本中关于`mtvec`的变更是这样表述的: +>"Optional vectored interrupt support has been added to the mtvec and stvec CSRs." + +也就是说支持`pc=BASE+4*CAUSE`的向量跳转的中断方式是可选的,而Bumblebee就恰好没有实现这个功能。 + +### 2. CSR `mtvec`的MODE部分 + +在riscv-privileged-v1.10.pdf文档中,`mtvect`MODE的合法值为: + +|Value|Name|Description| +|:-:|:-:|:--| +|0|Direct|All exceptions set pc to BASE.| +|1|Vectored|Asynchronous interrupts set pc to BASE+4×cause.| +|≥2| -| Reserved | + +但是Bumblebe的文档里却说: + +1. `mtvec.MODE != 6'b000011`则采用“默认中断模式” +2. `mtvec.MODE == 6'b000011`则采用“ECLIC 中断模式” + +这里有两个问题: + +1. RISC-V官方文档里MODE只有2个bit, Bumblebe却占6个bit +2. RISC-V官方文档里MODE有效取值只有1、2,但是Bumblebe却能取到3 + +所以这是直接的违反RISC-V的定义? + +### 3. `mtvt`、`mtvt2`、`mtvec` + +相对于标准文档,Bumblebe添加了`mtvt`、`mtvt2`两个CSR。 + +`mtvt` 存放中断向量表起始地址 + +`mtvt2` 存放非向量(矢量)中断**共享**入口地址,这里有两点 + + 1. `mtvt2`的最低位`mtvt2.MTVT2EN == 0`,则所有非向量中断共享的入口地址由CSR寄存器`mtvec`的值(忽略最低2位的值)指定 + 2. `mtvt2`的最低位`mtvt2.MTVT2EN == 1`,则所有非向量中断共享的入口地址由CSR寄存器`mtvt2`的值(忽略最低2位的值)指定 + +ECLIC的每个中断源均可以设置成向量或者非向量处理(通过寄存器`clicintattr[i].shv`),如果中断被配置为向量处理模式,则该中断被处理器内核响应后,处理器直接跳入该中断的向量入口(Vector Table Entry)存储的目标地址(ECLIC中断向量表的基地址保存在`mtvt`中,通过这个寄存器查得)。 + +*疑问:如果`mtvt2.MTVT2EN==0` 且在clicintattr[i]中配置成向量中断,就与riscv-privileged-v1.10.pdf中的"vectored interrupt"基本等价?只是一个是从`mtvt`中取出基址,一个是从`mtvec`中取出基址?* \ No newline at end of file diff --git a/learn/doc/mac_bash_profile b/learn/doc/mac_bash_profile index 6d3c43c..15876fc 100644 --- a/learn/doc/mac_bash_profile +++ b/learn/doc/mac_bash_profile @@ -6,10 +6,12 @@ export PATH=/usr/local/sbin:$PATH export PATH=$HOME/.local/bin:$PATH export PATH=$PATH:$HOME/workspace/esp/xtensa-esp32-elf/bin export PATH=$PATH:$HOME/workspace/esp/xtensa-lx106-elf/bin -export IDF_PATH=$HOME/workspace/esp/esp-idf +#export IDF_PATH=$HOME/workspace/esp/esp-idf +export IDF_PATH=$HOME/workspace/esp/ESP8266_RTOS_SDK export PATH=$PATH:/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/ export PATH=$PATH:$HOME/Library/Arduino15/packages/arduino/tools/avrdude/6.0.1-arduino5/bin export PATH=$PATH:/usr/local/opt/go/libexec/bin +export PATH=$PATH:/Users/ace/sys/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.2-20190521-0004/bin #多个GOPATH用';'分隔 go get会存到第一个目录 export GOPATH=$HOME/workspace/go:$HOME/workspace/web/qossvr/ export RTOS_PATH=$HOME/workspace/acecode/rtos/ diff --git a/learn/stm32/F103HAL/.settings/language.settings.xml b/learn/stm32/F103HAL/.settings/language.settings.xml index 65f4891..556530f 100644 --- a/learn/stm32/F103HAL/.settings/language.settings.xml +++ b/learn/stm32/F103HAL/.settings/language.settings.xml @@ -6,7 +6,7 @@ - + @@ -18,7 +18,7 @@ - + diff --git a/learn/stm32/USART.md b/learn/stm32/USART.md index 094d22b..184a597 100644 --- a/learn/stm32/USART.md +++ b/learn/stm32/USART.md @@ -111,6 +111,192 @@ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { } ``` +## USART转发优化版本 + +``` +#include "main.h" +#include "usart.h" +#include "gpio.h" +#include "stm32f1xx_hal.h" +#include "cmsis_os.h" + +#define BOARD_STANDARD +//#define BOARD_NBIOT + +// 如果要测试BOARD_STANDARD上的M6312,则必需: +// 1. 5V/2A电源要供电 +// 2. PC4_M6312_PWR_KEY 要设置为推挽输入,高电平 +// 3. J10接线端子用跳线帽接到M6312上 + +#define USART_RX_BUFSZ 32 +#define USART_TX_BUFSZ 32 +typedef struct { + uint8_t rxbuf[USART_RX_BUFSZ]; + uint8_t txbuf[USART_TX_BUFSZ]; + uint16_t rxwp; + uint16_t rxrp; + UART_HandleTypeDef *huart; + uint8_t rxdata; +} DebugUsart_t; + +#define INIT_DEBUG_USART(_name, _huart) \ + static DebugUsart_t _name = { \ + .rxwp = 0, \ + .rxrp = 0, \ + .huart = &_huart, \ + .rxdata = 0 \ + }; + + + +INIT_DEBUG_USART(__usart1, huart1) + +#if defined(BOARD_STANDARD) + INIT_DEBUG_USART(__usart2, huart2) + #define LED_GPIO_Port STANDARD_LED_GPIO_Port + #define LED_Pin STANDARD_LED_Pin + #define UsartA __usart1 + #define UsartB __usart2 +#elif defined(BOARD_NBIOT) + INIT_DEBUG_USART(__usart3, huart3) + #define LED_GPIO_Port NB_LED_GPIO_Port + #define LED_Pin NB_LED_Pin + #define UsartA __usart1 + #define UsartB __usart3 +#else + #error "must define board" +#endif + + + +void InitUsartTransfer(){ + if(HAL_OK != HAL_UART_Receive_IT(UsartA.huart, &UsartA.rxdata, 1)) { + Error_Handler(); + } + + if(HAL_OK != HAL_UART_Receive_IT(UsartB.huart, &UsartB.rxdata, 1)) { + Error_Handler(); + } +} + + +int ReadUsartData(DebugUsart_t *data, uint8_t *ch) { + uint16_t rxwp = data->rxwp; + if(data->rxrp == rxwp) { + // empty + return -1; + } + *ch = data->rxbuf[data->rxrp]; + data->rxrp = (data->rxrp + 1) % USART_RX_BUFSZ; + return 0; +} + + +void ReceiveUsartData(DebugUsart_t *data) { + if((data->rxwp + 1) % USART_RX_BUFSZ == data->rxrp) { + // full + goto end; + } + + data->rxbuf[data->rxwp] = data->rxdata; + + data->rxwp =(data->rxwp + 1) % USART_RX_BUFSZ; + +end: + if(HAL_OK != HAL_UART_Receive_IT(data->huart, &data->rxdata, 1)) { + //Error_Handler(); + } +} + +void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { + if(huart == UsartA.huart) { + return ReceiveUsartData(&UsartA); + } + + if(huart == UsartB.huart) { + return ReceiveUsartData(&UsartB); + } +} + + +int TransferData(DebugUsart_t *from ,DebugUsart_t *to) { + int cnt = 0; + while(cnt < USART_TX_BUFSZ) { + uint8_t ch; + if(0 != ReadUsartData(from, &ch)) { + break; + } + from->txbuf[cnt++] = ch; + } + + if(cnt > 0) { + HAL_UART_Transmit(to->huart, from->txbuf, cnt, 0xFFFF); + } + + return cnt; +} + +void TransferTask(void *arg) { + while(1) { + // 以下两次调用不得直接放到if表达式中 + int cnt1 = TransferData(&UsartA, &UsartB); + int cnt2 = TransferData(&UsartB, &UsartA); + + if(cnt1 == 0 && cnt2 == 0) { + osDelay(1); + } + } +} + +void LedTask(void *pdata) { + while(1) { + HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); + osDelay(100); + } +} + +osThreadDef(transferTask, TransferTask, osPriorityNormal, 0, 128); +osThreadDef(ledTask, LedTask, osPriorityLow, 0, 64); + +void InitDebug() { + InitUsartTransfer(); + +#if defined(BOARD_STANDARD) + HAL_GPIO_WritePin(M6312_PWRKEY_GPIO_Port, M6312_PWRKEY_Pin, GPIO_PIN_SET); +#endif + + osThreadId taskHandle; + taskHandle = osThreadCreate(osThread(transferTask), NULL); + if(taskHandle == NULL) { + Error_Handler(); + } + + taskHandle = osThreadCreate(osThread(ledTask), NULL); + if(taskHandle == NULL) { + Error_Handler(); + } +} + + +#if 1 +#include +#ifdef __GNUC__ + #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) +#else + #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) +#endif +PUTCHAR_PROTOTYPE +{ +#if defined(BOARD_CHINA_MOBILE_NBIOT) + HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF); +#endif + return ch; +} +#endif + + +``` + # USART1、USART2 DMA转发 ``` @@ -168,6 +354,11 @@ void ReceiveUsartDmaData(UsartDmaData_t *data, UART_HandleTypeDef *huart) { __HAL_UART_CLEAR_IDLEFLAG(huart); + //软件清空空闲中断标志位 + volatile tmp; + tmp =huart->SR; + tmp =huart->DR; + HAL_UART_DMAStop(huart); data->len = USART_RX_BUFSZ - data->dmarx->Instance->CNDTR; @@ -205,11 +396,10 @@ void USART1_IRQHandler(void) void USART2_IRQHandler(void) { /* USER CODE BEGIN USART2_IRQn 0 */ - + ReceiveUsartData(&huart2); /* USER CODE END USART2_IRQn 0 */ HAL_UART_IRQHandler(&huart2); /* USER CODE BEGIN USART2_IRQn 1 */ - ReceiveUsartData(&huart2); /* USER CODE END USART2_IRQn 1 */ } diff --git a/tools/mcu/rdserial.go b/tools/mcu/rdserial.go index 612aa5e..0216fd4 100644 --- a/tools/mcu/rdserial.go +++ b/tools/mcu/rdserial.go @@ -14,13 +14,16 @@ import ( "fmt" "github.com/tarm/serial" "log" + "os" ) func main() { var port string var baud int + var outfile string flag.StringVar(&port, "p", "/dev/cu.SLAB_USBtoUART", "serial port") flag.IntVar(&baud, "b", 115200, "baud rate default 115200") + flag.StringVar(&outfile, "o", "/dev/null", "output file path") flag.Parse() log.Printf("port: %s\n", port) @@ -31,17 +34,19 @@ func main() { log.Fatal(err) } - n, err := s.Write([]byte("test")) + f, err := os.OpenFile(outfile, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0600) if err != nil { - log.Fatal(err) + log.Fatalf("open file failed: %s\n", err) } + defer f.Close() for { buf := make([]byte, 4096) - n, err = s.Read(buf) + n, err := s.Read(buf) if err != nil { log.Fatal(err) } fmt.Printf("%s", string(buf[:n])) + f.Write(buf[:n]) } }