分类 未分类 下的文章

MCU(C89 Keil编译)上用printf(以及vsprintf), 会出现超过4个动态参数就会出问题的情况.
如: printf("%d,%d,%d,%d,%d", a,b,c,d,e);, 那么参数e很可能显示不准确. 原因不明.

好些天前做的, 记不住全部步骤了😅, 如前面的步骤不通, 再baidu一下吧😅
环境是win10.

步骤

  1. 下载mingw64_posix并解压;
  2. Vscode安装C/C++插件; 其他插件包括code runner, 我不确定是不是一定需要;
  3. 嵌入式插件可选, 包括keil assistant, PlatformIO IDE.
  4. 最重要的是要在代码根目录下建立.vscode的文件夹, 里面放四个文件(这几个保证正确)
  5. 非常重要, 编译器和调试器gcc.exe gdb.exe需要在vscode的终端中可以访问,即所在目录需要预先加入系统path. 否则编译会一直报错, 而且错误提示总让你以为是你的代码问题. 这一点我也很奇怪, json中已经有了编译器和调试器的配置为何再次需要.

文件

c_cpp_properties.json

里面的mingw64_posix路径根据实际情况修改

{   
  "configurations": [       
   {          
       "name": "Win32",       
       "includePath": [
       "${workspaceRoot}",               
       "D:/r/mingw64_posix/mingw64/include/**",               
       "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++",
       "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/x86_64-w64-mingw32",
       "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/backward",
       "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include",
       "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include-fixed",
       "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/include"
  ],      
  "defines": [
      "_DEBUG",
      "_WIN_DEBUG_",               
      "UNICODE",
      "__GNUC__=6",               
      "__cdecl=__attribute__((__cdecl__))"            
      ],           
  "intelliSenseMode": "msvc-x64",
  "browse": {              
      "limitSymbolsToIncludedHeaders": true,
      "databaseFilename": "",
      "path": [                   
          "${workspaceRoot}",                   
          "D:/r/mingw64_posix/mingw64/include/**",                   
          "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++",
          "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/x86_64-w64-mingw32",
          "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/backward",
          "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include",
          "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include-fixed",
          "D:/r/mingw64_posix/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/include"
         ]        
      }       
   }   
],   
 "version": 4
}

launch.json

{
  // 使用 IntelliSense 了解相关属性。 
  // 悬停以查看现有属性的描述。
  // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "name": "gcc.exe - 生成和调试活动文件",
      "type": "cppdbg",
      "request": "launch",
      "program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
      "args": [],
      "stopAtEntry": false,
      "cwd": "${fileDirname}",
      "environment": [],
      "externalConsole": false,
      "MIMode": "gdb",
      "miDebuggerPath": "D:\\r\\mingw64_posix\\mingw64\\bin\\gdb.exe",
      "setupCommands": [
        {
          "description": "为 gdb 启用整齐打印",
          "text": "-enable-pretty-printing",
          "ignoreFailures": true
        }
      ],
      "preLaunchTask": "C/C++: gcc.exe 生成活动文件"
    }
  ]
}

settings.json

{
  "files.associations": {
    "*.cjson": "jsonc",
    "*.wxss": "css",
    "*.wxs": "javascript",
    "*.task": "javascript",
    "*.html": "html",
    "esp.h": "c",
    "function2.h": "c",
    "common.h": "c",
    "driver.h": "c",
    "ts_service.h": "c",
    "stdlib.h": "c",
    "stdio.h": "c",
    "conio.h": "c",
    "time.h": "c",
    "math.h": "c",
    "uart_stub.h": "c"
  }
}

tasks.json

这个文件中的args就是gcc的args, 需要根据情况修改. 类似简单的makefile了.
多文件编译的时候, 这儿需要把需要编译的其他文件放进来.
需要编译引入预定义#define的时候, 加入-D预定义名

{
  "tasks": [
    {
      "type": "cppbuild",
      "label": "C/C++: gcc.exe 生成活动文件",
      "command": "D:\\Strawberryperl\\c\\bin\\gcc.exe",
      "args": [
        "-fdiagnostics-color=always",
        "-D_WIN_DEBUG_",
        "-g",
        "${file}","${fileDirname}\\common.c", "${fileDirname}\\driver.c", "${fileDirname}\\..\\..\\function2.c", 
        "${fileDirname}\\..\\..\\esp.c","${fileDirname}\\uart_stub.c",
        "-o",
        "${fileDirname}\\${fileBasenameNoExtension}.exe"
      ],
      "options": {
        "cwd": "${fileDirname}"
      },
      "problemMatcher": [
        "$gcc"
      ],
      "group": {
        "kind": "build",
        "isDefault": true
      },
      "detail": "调试器生成的任务。"
    }
  ],
  "version": "2.0.0"
}

#ifdef _WIN_DEBUG_  
#define DEBUG_PRINTF(format,...) printf("File: "__FILE__", Line: %05d: "format"\n", __LINE__, ##__VA_ARGS__)  
#else  
#define DEBUG_PRINTF(format,...)  
#endif  

上面这个代码的问题是只支持C99以上编译, 如果遇到了C89, 还不支持可变参数宏定义.
这个链接比较完整地进行了讨论. https://newbedev.com/define-macro-for-debug-printing-in-c
C89下可以这样定义

#ifdef _WIN_DEBUG_  
#define DEBUG_PRINTF(msg) printf msg
#else  
#define DEBUG_PRINTF(msg)
#endif  

int main(){
  DEBUG_PRINTF(("%s, %d\n", "abc", 123));  // 作者说使用的时候一定要用双括号. 
}

8266 进入烧录状态

8266进入烧录状态, 需要所谓的三个strapping管脚高低电平处在UART MODE, 其值为1
strapping管脚依次是[GPIO15,GPIO0,GPIO2], 组成的三位二进制数字就是strapping值

Strapping 管脚的 3 位值 [GPIO15,GPIO0,GPIO2] Boot 模式
7 [1,1,1] SDIO HighSpeed V2 IO
6 [1,1,0] SDIO LowSpeed V1 IO
5 [1,0,1] SDIO HighSpeed V1 IO
4 [1,0,0] SDIO LowSpeed V2 IO
3 [0,1,1] Flash Boot
2 [0,1,0] Jump Boot
1 [0,0,1] UART Boot
0 [0,0,0] Remapping

strapping值可以从8266串口的隐藏状态打印出来. 为啥是隐藏状态? 因为8266启动的时候, 会使用一个很不常见的串口波特率是74880(晶振为26M, 是默认的晶振. 如果是40M则是115200).

8266 SDK的make命令帮助

在项目目录中(有makefile和sdkconfig的文件夹)执行make help

Welcome to Espressif IDF build system. Some useful make targets:

make menuconfig - Configure IDF project
make defconfig - Set defaults for all new configuration options

make all - Build app, bootloader, partition table
make flash - Flash app, bootloader, partition table to a chip
make clean - Remove all build output
make size - Display the static memory footprint of the app
make size-components, size-files - Finer-grained memory footprints
make size-symbols - Per symbol memory footprint. Requires COMPONENT=<component>
make erase_flash - Erase entire flash contents
make monitor - Run idf_monitor tool to monitor serial output from app
make simple_monitor - Monitor serial output on terminal console
make list-components - List all components in the project

make app - Build just the app
make app-flash - Flash just the app
make app-clean - Clean just the app
make print_flash_cmd - Print the arguments for esptool when flash

See also 'make bootloader', 'make bootloader-flash', 'make bootloader-clean',
'make partition_table', etc, etc.

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>

void driverUartPrintf(const unsigned char *fmt, ...){
    va_list args;
    va_start(args, fmt);
    vsprintf(gucUartBuf, fmt,args);
    driverUartSendStr(gucUartBuf);  // 这一句要调用实际串口发送驱动
    va_end(args);
}

参考https://blog.csdn.net/zh458042230/article/details/8630469

这个是中断进程和主函数进程(或其他中断)都调用了同一个函数A的缘故. 中断进程会打断主函数进程而运行, 这时如果打断的地方是主函数进程运行函数A还没有结束的地方, 那么中断再次运行到函数A就会发生函数重入.
如果一定要这么做, 需要加上reentrant这个关键词.
当然中断最好是快进快出. 避免重入的方式, 一般应该是中断中设置需要做函数A任务的标志, 然后在主函数里去完成.

人类很容易把手段当成目标,从而忘记了本来的目标. 毛爷爷说这个就叫"教条化".
我发现很多宗教的问题, 甚至包括宗教本身就是这么产生的."教条化"这个词确实很形象.
孔夫子提出"礼",是针对东周末年朝纲崩坏, 诸侯甚至乱用天子之礼的问题, 目的是为了回复秩序. 而后来孔夫子的话就被当成圣旨不可违抗, 然后就变成了儒教.
同样老子为解释天地万物写了道德经, 里面少不了用一些象征比喻, 因为"道可道非常道", 本来就不好解释清楚嘛. 然后后人看不懂的比喻就强行解释, 或者强制解释为表面意思, 或者胡乱引申为其他意思. 有的是蠢, 有的是坏. 这就有了道教.
同理见其他宗教. 道教的三峰派, 印度教的性力派, 藏传佛教的密宗灌顶, 多多少少都把性从手段变成了目标.
而要是考量基督教,伊斯兰教和佛教的起源, 更都是将先贤的话教条化产生的宗教.

原始的目标只在一定的环境下存在. 教条化就是不顾原始目标,甚至不知道原始目标, 却一定要将手段实现.

甚至现在的企业管理也存在这样的问题. 比如马云的996是福报论. 996作为手段对于马云的目标来说确实是福报, 然而对于码农来说996变成了目标就不见得是福报了, 除非他和马云目标一致.

ACER进入普通BIOS是F2,然而很多选项看不到.
参考这篇文章: https://blog.csdn.net/zhuzhuxiazst/article/details/116143900

1 当前很多的PC厂商发布的计算机产品,在开机进入BIOS时,一般默认都隐藏了Advanced菜单,防止用户误操作导致笔记本的异常,用户无法直接调整advanced设置,比如更改SATA mode (IDE/AHCI),CPU,GPU,FAN等的设置.

2 一些厂商发布的BIOS的advanced 菜单可以通过进入bios后,使用组合键后重启再次进入bios或者直接使用组合键在bios中来开启.

A  LZ自己实测的一款笔记本通过组合键进入了bios advanced菜单.

笔记本: Acer TravelMate P246 系列。 BIOS: InsydeH20 V5.0.

开启advanced菜单的方式:

  1) 按电源键后 按F2 进入bios页面.

  2)  按住 Fn键,然后依次按 Tab键,asdfgho 字母键,松开Fn键,然后F10保存BIOS设置并重启(注意本处一定不能在F10重启时按电源键关闭电源,然后再开机).

  3) 按电源键 后按F2再次进入bios页面,便能看到advanced菜单(进入后LZ还是未能看到有更改sata controller模式的菜单,比较可惜)。(再次重启bios后,高级菜单会再次隐藏,需要再次循环以上操作来调出高级菜单.)

遥遥归途逢国庆,
工业限电停灯笼。
暮光长照红旗静,
思心念家急车行。
寅睡难眠母窸窣,
辰闹儿女父叹息。
浪里归湾湾不静,
树欲停而风不停。

七十二年又华诞,
甲子地支各一轮。
茹苦含辛终渐老,
忠孝未尽愧吾心。
碌碌人生是所愿,
空空苟活非所殷。
平平淡淡侬常在,
来年新月复照人。