故障现象:
使用emWin的机器上有包括中文、英文、俄文等十几种语言。测试发现保加利亚语有一个界面会偶发的卡死故障,其他语言不会。
原因分析:
emWin文字控件有25个字节的缓存控件,第25个字节固定为结束符。要显示的字符串字节长度如果在24个字节以内就可以完整显示,如果超过24个字节就只截取前24个字节显示。缓存的首地址以指针形式传给emWin,emWin依据UTF-8编码规则解析显示字符,直到碰到结束符才停止。
所有字符串采用UTF-8编码,下面是UTF-8编码介绍:
UTF-8是一种变长字节编码方式。对于某一个字符的UTF-8编码,如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的位数,其余各字节均以10开头。UTF-8最多可用到6个字节。
如表: 1字节 0xxxxxxx 2字节 110xxxxx 10xxxxxx 3字节 1110xxxx 10xxxxxx 10xxxxxx 4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
分析卡死界面保加利亚语和其他语言的不同点,发现保加利亚语有多个字符串超长,而其他语言没有。
打印超长字符的控件缓存中的数据,发现第24和第25个字节如下:
110xxxxx 00000000
emWin解析到第24个字节时,发现110开头就认为第24个和第25个字节共同组成一个字符编码(当然显示出来的是乱码),也就是说emWin没有把第25个字节看成是结束符,然后一直在内存中读下去而导致卡死。
解决办法:
取字符串时,先判断一下24字节最多能存放多少个字符的完整编码,比如某个保加利亚语字符串前10个字符的编码占23个字节,前11个字符编码占25个字节,那么就将前23个字节存入空间缓存中,第24个字节和25个字节填入结束符。