[原创] 【微雪 RP2040双核开发板】官方例程运行问题与解决

jinyi7016   2022-11-25 14:02 楼主

一、起因

在ubuntu上搭建好开发环境后,编译了官方的例程,但开发板的硬件与官方开发板的差异还是很大的,虽然编译了例程,但几乎没有可以运行运行的例程,所以,就重新编译了官方提供的例程。

文件是RP2040-LCD-1.28.zip,在ubuntu下进行编译。

但是编译好的文件,烧写到开发板上,运行到Paint_DrawImage后,就不再运行,也无法显示while中的六轴数据。

会卡在如下界面:

 

微信图片_20221125140141.jpg

 

重新下载官方文件中已经编译好的文件,就可以正常运行,自己编译的就不行。可以确定的是代码没有修改过。

gcc的版本是9.2.1

 

clipboard.png

cmake的版本是3.16.3

 

clipboard.png

猜可能是编译器的问题,知道官方使用的编译环境是哪些版本的。所以,按官方的方法,又在windows下搭建了环境。

重新编译后,一样的结果。

windows的编译时,打开的命令行要是Visual Studio 2019目录下的,运行的命令为:

cd E:\workspace_RP2040\pico-sdk-master
mkdir build
cd build
cmake -G "NMake Makefiles" ..
nmake

二、查找

通过逐行的排查,发现是Paint_DrawNum函数导致的,如果在while中调用了Paint_DrawNum函数,程序将会卡住。

 

找到该函数的源码如下,就把数字转换成字符串并显示。

#define ARRAY_LEN 255
void Paint_DrawNum(UWORD Xpoint, UWORD Ypoint, double Nummber,
                   sFONT *Font, UWORD Digit, UWORD Color_Foreground, UWORD Color_Background)
{
    char Str[ARRAY_LEN];
    sprintf(Str, "%.*lf", Digit + 1, Nummber);
    char *pStr = (char *)malloc((strlen(Str)) * sizeof(char));
    memcpy(pStr, Str, (strlen(Str) - 1));
    *(pStr + strlen(Str) - 1) = '\0';
    if (Digit == 0)
        *(pStr + strlen(Str) - 2) = '\0';
    // show
    Paint_DrawString_EN(Xpoint, Ypoint, (const char *)pStr, Font, Color_Foreground, Color_Background);
    free(pStr);
    pStr = NULL;
}

由于在程序开始时,在第一屏的显示上,也调用了这个函数,显示了一个flaot的小数,是可以正常的,说明函数本身应该是没有问题的。

但到while中却显示不正常,确实有一些不解。

唯一不同的,就是字号的不同。初始化进的字号是20,while中的字号是16.所以,把while中的字号修改成20再测试时,也是一样的结果。

 

 

三、解决

 

从Paint_DrawNum的源码上看,逻辑应该是没有问题的,在linux也单独测试了这个函数,也是可以正常输出的,那么问题就可能出在交叉编译时,编译器对这个函数的处理上。

如下,是测试进的程序

 

clipboard.png

 

整个函数上看,唯一可能有问题的就是malloc与free这些涉及到内存处理的函数了,所以,把这个函数修改成如下

 

    #define ARRAY_LEN 255
void Paint_DrawNum(UWORD Xpoint, UWORD Ypoint, double Nummber,
                   sFONT *Font, UWORD Digit, UWORD Color_Foreground, UWORD Color_Background)
{
#if 1
	char Str[ARRAY_LEN];
    sprintf(Str, "%.*lf", Digit, Nummber);
   // char *pStr = (char *)malloc((strlen(Str)) * sizeof(char));
   // memcpy(pStr, Str, (strlen(Str) - 1));
  //  *(pStr + strlen(Str) - 1) = '\0';
  //  if (Digit == 0)
   //     *(pStr + strlen(Str) - 2) = '\0';
    // show
    Paint_DrawString_EN(Xpoint, Ypoint, (const char *)Str, Font, Color_Foreground, Color_Background);
   // free(pStr);
   // pStr = NULL;
#endif

}

再烧写到开发板上,程序顺利运行。

 

微信图片_20221125140138.jpg

 

本帖最后由 jinyi7016 于 2022-11-25 14:04 编辑

回复评论 (6)

微雪官方给的例程,和开发板不配套?

点赞  2022-11-25 14:35
引用: nmg 发表于 2022-11-25 14:35 微雪官方给的例程,和开发板不配套?

可能是SDK版本或是编译器版本不同的原因,毕竟官方提供的可烧写文件是正常的。

点赞  2022-11-25 14:43

这个效果看着相当不错啊

在爱好的道路上不断前进,在生活的迷雾中播撒光引
点赞  2022-11-27 08:51

这个问题是因为在while或者for循环中,编译器自作主张认为你是重复做无意义的事情,所以进行了优化。你会发现都是在while或者for中有问题,就是因为编译器聪明过头,认为你在做无意义重复的事,虽然实际上我们的重复是有意义的。

将相应的变量加上volatile修饰就可以了。

或者取消编译器优化,优化等级设置为-O0,这样程序会很大,效率低,不是我们期望的,一般我们还是会默认开编译器优化的。

点赞  2022-12-3 23:05

楼上的大佬对这个理解到位呀,看后感触非凡。微雪的产品,也很给力。

点赞  2022-12-13 07:39

楼主重启之后有没有遇到黑屏得情况?

点赞  2023-3-5 02:23
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复