狮山网站设计跨境电商seo什么意思
最近使用swm341s 调试了一个显示屏
中间遇到了一些个问题卡了一些时间,特此做一个总结和记录,防忘记
移植使用的是Freertos + LVGL8.3.3
- 芯片内部带了一个8M的SDRAM,需要在lv_conf.h文件中定义一个SDRAM2作为SPI Flash的映射地址,作为固定存储的空间,把一些图片,字体放入编译的时候,映射到这个位置,并且下载会存入spi flash中
数据将在启动时从加载地址( SPI Flash)复制到 SDRAM。
例如,本次设置的SDRAM2的空间是4MB。
#define LV_ATTRIBUTE_LARGE_CONST __attribute__((section(".SDRAM2")))
#define LV_ATTRIBUTE_LARGE_RAM_ARRAY __attribute__((section(".SDRAM1")))
并且需要在sct文件中设置 spi flash 映射地址
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************LR_IROM1 0x00000000 0x00080000 { ; load region size_regionER_IROM1 0x00000000 0x00080000 { ; load address = execution address*.o (RESET, +First)*(InRoot$$Sections).ANY (+RO).ANY (+XO)}RW_IRAM1 0x20000000 0x00010000 { ; RW data.ANY (+RW +ZI)}ER_SDRAM1 0x80000000 0x00400000 { ; execution address*(.SDRAM1)}
}LR_SPIFLASH 0x70000000 0x01000000 { ; load region size_regionER_SDRAM2 0x80400000 0x00400000 { ; execution address*(.SDRAM2)}
}
- LVGL 的任务机制本身不是线程安全的,在对如何LVGL控件的操作时,必须在同一线程中调用,如果直接在其他线程中操作UI,可能会导致竞态条件或数据不一致的问题,甚至程序崩溃。
我开始的时候没有注意到这个点,在其他任务中也去控制了一些控件,就导致了刷新不正常,也会导致进入hardfault,所以后面改成了,增加一个队列,在lvgl任务中接收队列来调整需要修改的数据
此时,我还犯错了,创建队列的时候,选择的size是u16格式,
MSG_LvglQueue = xQueueCreate(LVGL_QUEUE_MAX, sizeof(uint16_t) );
但是我在用的时候,又传递的是int类型的数据,导致传输的数据异常了。 如果数据长度不匹配,传递的时候使用的是char类型的数据,则可能会导致内存泄漏而进入hardfault。
- 中断的选择
本芯片的中断,没有group的概念,全是抢占优先级,没有子优先级,所以无需设置 NVIC_SetPriorityGrouping 函数,
并且本芯片的优先级范围是0-7;
在freertosConfig.h文件中
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5// 允许 FreeRTOS API 的最高优先级 = 5
所以硬件中断里面,如果需要安全的使用到rtos的API函数,则中断优先级必须小于等于5
在初始化的时候,就可以设置中断优先级,比如我现在设置串口1中断是6
NVIC_SetPriority(UART1_IRQn, 6);
在中断中需要使用合适的api函数
比如队列发送,需要使用带ISR的
xQueueSendFromISR (MSG_UART_RXQueue, &s_uart1RxBufLen, 0);
使用临界区函数
BaseType_t xWasEnabled;xWasEnabled = taskENTER_CRITICAL_FROM_ISR(); //进入基本临界区/*填写代码*/taskEXIT_CRITICAL_FROM_ISR(xWasEnabled); //退出基本临界区
我在这里犯错了,因为没有注意到中断优先级的问题,导致默认的时候串口1中断优先级是默认的0,在大部分情况下是正常的,但是总是偶发性的出现,在任务中,接收的队列一直被阻塞了,本任务也不在运行,但是其他任务运行正常。还有很小概率出现hardfault。就是中断中发送队列的时候,破坏了队列的表,导致被死锁了
- 串口引脚RX,好像是不带内部上拉的,如果初始化完后,该引脚又是悬空的,就会一直进入串口中断,在这上面,我也吃亏了,因为没有注意到会进入中断,所以在中断中,最开始调试的时候,随便写了一个接收的buf,多次进入串口中断后,就内存泄漏进入了hardfault
需要硬件上拉,或者不初始化中断
在初始化的时候,RXThresholdIEn 代表是否使能该中断,RXThreshold 是代表FIFO里面的数据个数产生中断,我在这个地方犯错的就是,我设置为1,总是需要接收1个字节后,填入了FIFO中,第二个字节才产生中断, 设置为0,就会没个字节的接收都会产生中断,这里手册中有明确的写,但是我没有注意到。
void uart1_init(void)
{UART_InitStructure UART_initStruct;PORT_Init(PORTN, PIN5, PORTN_PIN5_UART1_RX, 1); //GPION.5配置为UART1输入引脚PORT_Init(PORTB, PIN0, PORTB_PIN0_UART1_TX, 0); //GPIOB.0配置为UART1输出引脚UART_initStruct.Baudrate = 19200;UART_initStruct.DataBits = UART_DATA_8BIT;UART_initStruct.Parity = UART_PARITY_NONE;UART_initStruct.StopBits = UART_STOP_1BIT;UART_initStruct.RXThreshold = 0;UART_initStruct.RXThresholdIEn = 1;UART_initStruct.TXThreshold = 0;UART_initStruct.TXThresholdIEn = 0;UART_initStruct.TimeoutTime = 3;UART_initStruct.TimeoutIEn = 1;UART_Init(UART1, &UART_initStruct);UART_Open(UART1);DMA_InitStructure DMA_initStruct;DMA_initStruct.Mode = DMA_MODE_SINGLE;DMA_initStruct.Unit = DMA_UNIT_BYTE;DMA_initStruct.Count = DMA_PRINTF_LEN_MAX;DMA_initStruct.SrcAddr = (uint32_t)DMA_Uart1Buffer;DMA_initStruct.SrcAddrInc = 1;DMA_initStruct.DstAddr = (uint32_t)&UART1->DATA;DMA_initStruct.DstAddrInc = 0;DMA_initStruct.Handshake = DMA_CH1_UART1TX;DMA_initStruct.Priority = DMA_PRI_HIGH;DMA_initStruct.INTEn = 0;DMA_CH_Init(DMA_CH1, &DMA_initStruct);
}
- DMA,两组4个通道,例如某段DMA搬运用CH0,那CH0就被占用了,只能用CH1,CH2,Ch3