数据源不定时间段后连接中断(解决方法:连接关闭后设置自启动,重新自动连接

本文介绍了解决数据库连接不定时中断的问题,通过配置数据源验证机制实现自动重连,并提供了Wildfly服务器配置双物理机和单物理机数据源的示例。

数据源不定时间段后连接中断(解决方法:连接关闭后设置自启动,重新自动连接。问题描述如下 ):



数据源原配置文件如下:(备注:划红线的2行出现冲突)


修改后的数据源配置如下:(解决不定时间数据库连接中断问题)(备注:校验代码的(部分)作用:当数据库连接断开后,重新自动连接。 )
                    <validation>
                        <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker"/>
                        <check-valid-connection-sql>select 1 from dual</check-valid-connection-sql>
                        //<validate-on-match>false</validate-on-match>
                        <background-validation>true</background-validation>
                        <background-validation-millis>200000</background-validation-millis>
                        <use-fast-fail>false</use-fast-fail>
                        <stale-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleStaleConnectionChecker"/>
                        <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleExceptionSorter"/>
                    </validation>

(补充知识)工程中wildfly服务器配置文件的配置双物理机数据源(配置代码):
<connection-url>jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=10.100.24.30)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=10.100.24.31)(PORT=1521))(LOAD_BALANCE=yes)(FAILOVER=on))(CONNECT_DATA=(SERVICE_NAME=orcl )))</connection-url>
工程中wildfly服务器配置文件的配置一个物理机数据源(配置代码):
<connection-url>jdbc:oracle:thin:@192.168.2.231:1521:orcl</connection-url>
备注: 部署工程时数据库部署在多个物理机上防止一个数据库物理机挂了影响工程,当数据库部署在多个物理机上时,可以创建一个虚拟机数据库用于关联多个
物理机数据库,从而在服务器的数据源连接配置文件中只需要一个ip连接即可)
整个数据源配置代码如下(双物理机配置):
          <datasources>
                <datasource jta="true" jndi-name="java:jboss/datasources/OracleDS_UAM" pool-name="OracleDS_UAM" enabled="true" use-java-context="true" use-ccm="true">
                    <connection-url>jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=10.100.24.30)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=10.100.24.31)(PORT=1521))(LOAD_BALANCE=yes)(FAILOVER=on))(CONNECT_DATA=(SERVICE_NAME=orcl )))</connection-url>
                    <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
                    <driver>oracle</driver>
                    <pool>
                        <min-pool-size>10</min-pool-size>
                        <max-pool-size>100</max-pool-size>
                        <prefill>true</prefill>
                        <use-strict-min>false</use-strict-min>
                        <flush-strategy>FailingConnectionOnly</flush-strategy>
                    </pool>
                    <security>
                        <user-name>sdsy</user-name>
                        <password>sdsy1qaz@WSX.</password>
                    </security> 
               <validation>
                        <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker"/>
                        <check-valid-connection-sql>select 1 from dual</check-valid-connection-sql>
                        <background-validation>true</background-validation>
                        <background-validation-millis>200000</background-validation-millis>
                        <use-fast-fail>false</use-fast-fail>
                        <stale-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleStaleConnectionChecker"/>
                        <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleExceptionSorter"/>
                    </validation>
                </datasource>
                <drivers> 
                    <driver name="oracle" module="com.oracle">
                        <xa-datasource-class>oracle.jdbc.xa.client.OracleXADataSource</xa-datasource-class>
                    </driver>
                </drivers>
     </datasources>

<think>好的,我现在需要帮助用户解决在GD32E230芯片上通过串口使用DMA进行不定长字节接收与发送,并实现接收超时中断的问题。首先,我得回忆一下GD32E230的UART和DMA相关寄存器配置,以及如何结合中断处理不定长数据。 用户提到了DMA发送和接收,特别是接收超时中断。根据引用[1]中的示例,发送DMA需要先禁用,设置地址和数据长度,再使能。但接收部分,尤其是处理不定长数据,可能需要不同的方法不定长接收通常需要检测空闲中断或者使用超时机制,这里用户明确要求超时中断。 首先,我需要确定GD32E230的UART是否支持接收超时中断功能。查阅手册,发现GD32E230的UART有接收超时中断(Receiver Timeout Interrupt),当接收空闲一段时间后触发。这可以用来判断一帧数据的结束。 接下来是DMA的配置。对于不定长接收,DMA应该配置为循环模式还是正常模式?如果是循环模式,可能会覆盖未处理的数据,所以可能更适合使用正常模式,每次接收一定长度的数据,但不定长的话,可能需要动态调整。不过GD32E230的DMA可能支持在传输过程中暂停或者自动重新配置,需要进一步确认。 或者,结合UART的IDLE中断和DMA传输完成中断。当UART检测到总线空闲时触发中断,此时读取DMA接收到的数据长度。但用户要求的是超时中断,可能类似IDLE中断的处理方式。不过GD32E230是否有这个功能需要确认。假设支持接收超时中断,那么配置相应的超时时间,比如每收到一个字节后,如果在设定时间内没有新数据,则触发超时中断。 然后,DMA接收的配置需要设置内存地址为缓冲区,数据长度设为最大可能长度,这样DMA会持续接收数据直到缓冲区满或者被停止。当超时中断发生时,计算已经接收的数据量,可能是当前DMA传输剩余计数值,从而得到实际接收的字节数。 发送部分相对简单,如引用[1]中的MYDMA_Send函数,设置DMA的源地址和长度,启动传输。需要注意发送完成标志的检测,可能需要等待DMA传输完成或使用中断。 关于代码实现,首先初始化UART,启用DMA接收和发送功能,配置DMA通道,设置中断服务程序处理超时中断。在超时中断中,停止DMA接收,计算接收到的数据长度,处理数据,然后重新配置DMA以继续接收。 可能的问题点包括正确配置超时时间,确保中断服务程序高效处理,避免数据覆盖。此外,DMA接收缓冲区的管理也很重要,可能需要双缓冲区或者循环缓冲区来处理连续的数据流。 需要参考GD32E230的参考手册,确认UART和DMA寄存器的具体配置步骤,比如使能接收超时中断的寄存器位,设置超时时间,DMA的传输模式(如循环模式或正常模式),中断使能等。 此外,用户可能还需要处理接收完成后的数据,比如发送回显,这时需要结合DMA发送功能,在接收超时中断处理中启动发送流程。 最后,测试代码的正确性,确保在不定长数据接收时能够正确触发超时中断,并准确获取数据长度,同时处理发送和接收的协调,避免冲突。</think>### GD32E230串口DMA不定长接收与发送实现 #### 1. 硬件配置与初始化 1. **GPIO配置** 配置UART引脚为复用功能模式(如PA9为TX,PA10为RX): ```c rcu_periph_clock_enable(RCU_GPIOA); gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_9 | GPIO_PIN_10); gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_9 | GPIO_PIN_10); // AF1为USART0复用功能 ``` 2. **UART初始化** 使能UART时钟,配置波特率、数据位、停止位,并开启接收超时中断: ```c rcu_periph_clock_enable(RCU_USART0); usart_deinit(USART0); usart_baudrate_set(USART0, 115200); usart_parity_config(USART0, USART_PM_NONE); usart_word_length_set(USART0, USART_WL_8BIT); usart_stop_bit_set(USART0, USART_STB_1BIT); usart_receive_timeout_enable(USART0); // 使能接收超时功能 usart_timeout_value_set(USART0, 0x20); // 设置超时时间(根据波特率计算) usart_interrupt_enable(USART0, USART_INT_RT); // 使能接收超时中断 ``` 3. **DMA配置** 初始化DMA通道(以DMA0通道2为例)用于接收,通道3用于发送: ```c dma_parameter_struct dma_init_struct; rcu_periph_clock_enable(RCU_DMA); // 接收DMA配置 dma_deinit(DMA0, DMA_CH2); dma_init_struct.direction = DMA_PERIPH_TO_MEMORY; dma_init_struct.memory_addr = (uint32_t)rx_buffer; // 接收缓冲区地址 dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; dma_init_struct.periph_addr = (uint32_t)&USART_RDATA(USART0); dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; dma_init_struct.number = MAX_RX_LEN; // 最大接收长度 dma_init_struct.priority = DMA_PRIORITY_HIGH; dma_init(DMA0, DMA_CH2, &dma_init_struct); usart_dma_receive_config(USART0, USART_DENR_ENABLE); // 使能UART DMA接收 ``` #### 2. 超时中断与数据处理 1. **中断服务函数** 在超时中断中停止DMA,计算已接收数据长度: ```c void USART0_IRQHandler(void) { if (usart_interrupt_flag_get(USART0, USART_INT_FLAG_RT)) { usart_interrupt_flag_clear(USART0, USART_INT_FLAG_RT); dma_channel_disable(DMA0, DMA_CH2); // 停止DMA接收 uint32_t remaining = dma_transfer_number_get(DMA0, DMA_CH2); rx_data_len = MAX_RX_LEN - remaining; // 计算实际接收长度 usart_flag_clear(USART0, USART_FLAG_RT); dma_channel_enable(DMA0, DMA_CH2); // 重启DMA接收 } } ``` 2. **DMA发送实现** 发送函数需先禁用DMA通道,配置参数后重新使能(参考引用[1]): ```c void MYDMA_Send(uint8_t *data, uint16_t len) { dma_channel_disable(DMA0, DMA_CH3); dma_memory_address_config(DMA0, DMA_CH3, (uint32_t)data); dma_transfer_number_config(DMA0, DMA_CH3, len); dma_channel_enable(DMA0, DMA_CH3); while (!usart_flag_get(USART0, USART_FLAG_TC)); // 等待发送完成 } ``` #### 3. 关键优化点 - **超时时间计算** 超时值需根据波特率调整,公式为: $$Timeout = \frac{3.5 \times (8 + DataBits)}{BaudRate} \times SystemClock$$ 例如:115200波特率下,超时值约为10ms[^2]。 - **双缓冲区机制** 使用双缓冲区避免数据覆盖,超时中断处理期间切换缓冲区。 - **低功耗优化** 在空闲时关闭DMA时钟,通过中断唤醒(参考引用[3])。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值