本文共 5626 字,大约阅读时间需要 18 分钟。
1. 输出控制符(%)
1、%d、 %2d、%02d的区别
%d:普通的输出
%2d:宽度为2位、右对齐方式输出,若不够两位,左边补空格。
%02d:宽度为2位、右对齐方式输出,若不够两位,左边补0。
%#x:带格式输出,在输出前面加上0x
2、%m.ns
宽度为m位、右对齐方式输出,显示n位,若不够m位,左边补空格。
2. strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,指向str2在str1中首次出现的位置。
strstr("Helloworld!","world");
3. SRAM:静态随机存取存储器
所谓的“静态”,是指这种存储器只要保持,里面储存的数据就可以恒常保持。相对之下,(DRAM)里面所储存的数据就需要周期性地更新。然而,当电力供应停止时,SRAM储存的数据还是会消失,这与在断电后还能储存资料的或是不同的。
ROM:只读存储器PROM:可编程只读存储器EPROM:可擦可编程只读存储器EEPROM:上电可擦可编程只读存储器RAM:随机存储器SRAM:静态随机存储器DRAM:动态随机存储器常用的Flash:NorFlash、NANDFlash、EEPROM
4. updatebak是一个core和app的打包下载文件,core和app本身都有签名,updatebak也有签名,在下载的时候都会进行校验,校验失败不会进行更新。
apupdate是一个core和app的打包下载文件,core和app本身都有签名,apupdate不签名,在下载时apupdate不校验,apupdate里面的文件会进行校验;
5. 程序编译失败,找不到“core_cm4.h”文件。
添加系统的头文件库,C:\Keil_v5\ARM\Pack\ARM\CMSIS\4.3.0\CMSIS\Include,如下所示。
6. 打印调试信息的技巧:
1)打印函数名称、调试信息所在行号的语句;
2)调试加延时;
3)调试用while(1)语句;
dev_debug_printf("%s(%d):enter dev_lcd_test\r\n", __FUNCTION__, __LINE__); dev_user_delay_ms(10); sdkmSleep(10);while(1);
7. 编译报错如下:
error: #167: argument of type "const u8 *" is incompatible with parameter of type "u8 *"
原代码如下:
const u8 icon_battery_mono_3[] = {};dev_lcd_monochrome(0, 2, width, height, icon_battery_mono_3);
使用(u8 *)进行强制类型转换,修改代码如下:
dev_lcd_monochrome(0, 2, width, height, (u8 *)icon_battery_mono_3);
8. 编译报错如下:
错误原因:代码里面屏蔽掉了
9. 代码空间不足,修改dev_memoryalloc\dev_memoryalloc.c文件,把堆的空间减小,全局变量的空间就变大了。
#define __HEAP_START_ALLOC_MAXSIZE 0xF0000 //堆空间,960K改为:#define __HEAP_START_ALLOC_MAXSIZE 0xDC000 //880K
10. 编译报错“.\obj\core.axf: Error: L6218E: Undefined symbol DCMI_ClearITPendingBit (referred from drv_scanner.o).”
1、已经包含了头文件,如下所示:
#include "..\sdk\Libraries\MHSCPU_Driver\inc\mhscpu_dcmi.h"
2、在“Options for Target”中“C/C++”选项中的“Include Paths”中已添加mhscpu_dcmi.h文件,如下所示。
..\src\sdk\Libraries\MHSCPU_Driver\inc
3、没有添加源文件
1)源文件在如下路径:
src\sdk\Libraries\MHSCPU_Driver\src
2)添加到Keil工程的“MHSCPU_Driver”文件夹中,如下所示。
11. do{}while(0)语句有以下2个作用:
1)随时跳出语句(break);
2)使函数有统一的出口(go to)。
12. .gitignore文件的使用方法:
1)单独提交.gitignore文件到仓库中;
2)git pull仓库下的.gitignore文件;
3)添加其它文件。
13. PADS工具的使用方法:
1)原理图关联PCB图。在原理图界面点击"工具"菜单中的"PADS Layout..."选项,在弹出的对话框中点击"关闭",即可完成与PCB图的关联;
单次只打开一个SCH和PCB文件,方便关联上,否则容易出现关联不上的问题。
2)PCB图一般只看有元器件的底层和顶层,切换PCB所在层的指令如下:
1、底层:Z + B
2、顶层:Z + T
3、其它层:Z + 1、2、3、4....
3)旋转PCB视图。点击工具栏中的旋转按钮,如下图所示:
4)PCB视图显示网络。点击"设置"菜单中的"显示颜色"选项,在弹出的对话框中点击"网络名",再点击"确认"即可,如下图所示。
5)选择网络。在原理图界面的右键菜单中选择"选择网络"选项,如下图所示。点击原理图中的网络,即可完成与PCB图中的网络关联。
6)选择元器件。在原理图界面的右键菜单中选择"选择元件"选项,如下图所示。点击原理图中的元器件,即可完成与PCB图中的元器件关联。
14. 记录电池放电状态的结构体定义如下:
typedef struct { u32 m_timeid; u8 m_chargeflag; //未对齐 u16 m_vol; //未对齐 u8 m_batlev; }record_bat_status_t;
调试发现,m_batlev元素打印出的数据异常,原因是结构体中元素定义的大小未对齐,正确的结构体定义如下所示:
typedef struct { u32 m_timeid; u16 m_vol; u8 m_chargeflag; u8 m_batlev; }record_bat_status_t;
15.
char *strtok(char *s, char *delim);
s:要分解的字符串 delim:分隔符字符
使用举例如下所示:
p = strtok(&src[8], ",");p = strtok(NULL, ",");
首次调用时,s指向要分解的字符串,之后再次调用要把s设成NULL。
16. 示波器测量频率的方法
1)按“Measure”测量按键;
2)按“添加测量”对应的按键;
3)滚动“通用a”旋钮,选择“频率”选项,按“only”按键下面的第一个按键,确认选择;
4)按两下“Menu Off”按键,清除菜单选项;
5)旋转“标度”旋钮,把时间标度尽量调低,使得波形放大后能清晰的呈现;
6)探头点中待测试的管脚;
7)点击“Run/Stop”按键,暂停波形;
8)点击放大镜的搜索按键;
9)放大并使用光标测量一个完整波形的频率,就是正确的频率值。
17.c语言中数字后面带个U是什么意思,例如:
GPIO->ALT[portnum] &= ~(0x03U<<(pin_num<<1));
C语言中整形常量默认为有符号int,加U会把常量以usigned int存储,这样第31位数据就可以用了。
18.现在常用的编译器多认为int和long int相同,均为4字节,short为2字节,char为1字节;
19.共用体(union)的所有成员占用同一段内存,修改一个成员会影响其余所有成员;
20.Beyond Compare软件,进行文件比较时,显示文件不同,但是打开文件之后,里面的内容却一样。要做以下的操作:
1)设置如下图所示:
2)刷新如下图所示:
21.Beyond Compare软件,设置默认为ANSI格式,步骤如下所示:
工具 -> 文件格式 -> 选中C,C++-> 转换->编码->选“ANSI”
22.函数头注释格式举例如下:
/** * @brief 国密sm2签名运算 * @param [in] pHash:hash值 * @param [in] pPkeyD:私钥 * @param [out] pSign:签名数据 * @retval 0:成功 other:错误 */
23.文件头注释格式
文件头注释格式举例如下所示:
/** * @file dev_wifi.c * @author zhangsan * @brief wifi设备层代码,包含wifi对外接口及内部接口的代码实现 * @note 需引用dev_wifi.h头文件 * @since 2019.6.10 初始代码 */
24.G500模块下载底包的方法:
1)使用coolwatcher工具;
2)先下载boot.lod文件,再下载app.lod文件,如下所示:
1、35000.1000.00.03.21.23_022_boot.lod;
2、35000.1000.00.03.21.23_022_app.lod;
25.全双工、半双工、单工的概念
全双工:允许数据在两个方向上同时传输,它在能力上相当于两个单工通信方式的结合。全双工指可以同时(瞬时)进行信号的双向传输
(A→B且B→A)。指A→B的同时B→A,是瞬时同步的。
半双工:数据传输允许数据在两个方向上传输,但是,在某一时刻,只允许数据在一个方向上传输;
单工:只允许甲方向乙方传送信息,而乙方不能向甲方传送;
26.__IO,_I,_O的定义
#define __I volatile const //*!
27.mtd0是动态文件系统,存放动态生成的文件,例如"/mtd0/btparam" 。mtd2是静态文件系统,存放预先定义的可下载文件。
28.以下定义,表示6个字节的16进制数;
#define BT_PARAM_MAC_DEFAULT "\x12\x34\x56\x78\x90\x12"
29.mtd2File结构体中的"reserved"参数,用于备份保存apacquirer.pk公钥证书,4K大小;
30.SPILCM_A0_HIGH和SPILCM_A0_LOW的定义如下所示:
#define SPILCM_A0_HIGH dev_gpio_set_value(SPILCM_A0, 1) //发送数据#define SPILCM_A0_LOW dev_gpio_set_value(SPILCM_A0, 0) //发送指令
31.gitlab中的merge请求,change部分的显示不完整,可以使用Microsoft Edge浏览器打开查看;
gitlab无法显示登录界面,使用Microsoft Edge浏览器打开即可;
32.memcmp()与strcmp()、memcpy()与strcpy()函数接口的差异是,前者多一个数据长度的参数,
memcmp()与strncmp()参数一致;
33.IOCTL函数修改lParam参数的方法,如下所示:
(*(u8*)lParam) = dev_audio_getplayingstatus();(*(u32*)lParam) = dev_audio_get_volume();
34.Keil报错如下所示:
..\src\sdk/..\sdk\Libraries\Device\MegaHunt\mhscpu\Include\mhscpu.h(194): error: #40: expected an identifier typedef enum {FALSE = 0, TRUE = !FALSE} Boolean;
原因是未包含以下头文件:
#include "sdk/mhscpu_sdk.h"
35.函数指针的定义
如果在程序中定义了一个函数,那么在编译时系统就会为这个函数代码分配一段存储空间,这段存储空间的首地址称为这个函数的地址。
而且函数名表示的就是这个地址。既然是地址我们就可以定义一个指针变量来存放,这个指针变量就叫作函数指针变量,简称函数指针。
函数指针的定义方式为:
函数返回值类型 (* 指针变量名) (函数参数列表);
36.POS没有焊纽扣电池,机器起不来,因为安全保护区域没有供电;
37.FileZilla文件传输失败的原因,大多是权限不够,解决方法如下所示:
sudo chmod -R 777 ./
38.WORD中插入代码的方法:
1)将代码拷贝到以下网址:
2)点击“Highlight!”后复制代码;
3)在WORD中新建一个一行一列的表格;
4)将复制的代码粘贴到表格中;
5)拖动表格边框调整代码位置,将表格设置为无边框;
39.字符串中嵌套字符串
可以在双引号前面加个转义符 \ ,即反斜杠。如"Hello \"W \"orld",会输出 Hello "W"orld