又见炊烟升起

导航

=嵌入式开发中的一句话备忘 - 单片机&RTOS系统

目录

Cortex-M核 +RTOS开发

C语言
Linux软件开发
其他
RT-Thread

 

 

51单片机备忘

 

Cortex-M核 +RTOS开发

//野火F407开发板的DAP仿真器配置:

 

//Keil 中1个汉字是双字节,删除需要按2次,如下操作可以解决:

 

 

C语言

 // objdump -t obj:输出目标文件的符号表

 
 
// GNU binutils(二进制工具集),主要包括GNU链接器(ld)和GNU汇编器(as)和一些工具组成。这些工具有:
addr2line – 可执行文件地址到源文件名和行信息转换工具。
ar – 归档文件(archive)管理工具。
c++filt – C++符号过滤工具。
gprof – 显示程序profiling(中文待定“剖析”?)信息工具。
nlmconv – 转换目标代码至NLM(NetWare Loadable Module)。
nm – 从目标代码文件中列举出所有变量。
objcopy – 转换目标文件格式。
objdump – 显示目标文件信息。
ranlib – 为归档文件生成索引以加快对归档文件的访问。
readelf – 显示ELF(Executable and Linking Format)文件信息。
size – 列出目标文件或模块的大小信息。
strings – 显示文件中的可打印信息。
strip – 删除文件中的连接符号,以减少目标文件大小。
windres – MS Windows 资源文件编译工具,这个对我们用不到。
 
 
 
 
 
 
 
 
//查看可执行文件由那些库组成:
[nisy@localhost test]$ ldd ./gtk-test‘
linux-gate.so.1 (0xb7710000)
libpoppler-glib.so.8 => /run/media/nisy/sda7_ubuntu/opt/_source_code_/_code/poppler/poppler-0.48.0_gtk/glib/libpoppler-glib.so.8 (0xb76ae000)
libgtk-3.so.0 => /lib/libgtk-3.so.0 (0xb6f32000)
libgdk-3.so.0 => /lib/libgdk-3.so.0 (0xb6e41000)
libcairo.so.2 => /lib/libcairo.so.2 (0xb6d02000)
// By default, gcc searches the following directories for header files:
/usr/local/include/
/usr/include/
and the following directories for libraries:
/usr/local/lib/
/usr/lib/
 
// ar 程序将使我们有机会将多个目标文件打包成一个库文件;objcopy可以让我们将一种格式的目标文件内容转换成另一种格式的目标文件。
目前比较流行的目标文件格式有COFF(Common Object File Format)和ELF(Executable and Linking Format)。
 
//gcc的调试信息:
-g参数:
产生符号调试工具(GNU 的 gdb)所必要的符号信息,要想对源代码进行调试,就必须加入这个选项。 g 也分等级,默认是-g2, -g1 是最基本的, -g3 包含宏信息,-g0则没有调试信息
 
-ON参数:
指定代码的优化等级为 N,可取值为 0、 1、 2、 3; O0 没有优化, O3 优化级别最高
 
//可以通过code block的source code formatter 插件功能优化代码的格式,也可以使用:
indent -kr -i8 main.c
来优化代码风格,-kr选项表示K&R风格,-i8表示缩进8个空格的长度。如果没有指定-nut选项,则每8个缩进空格会自动用一个Tab代替,基本上-kr -i8这两个参数就够用了。
 
//make -n 即显示会执行什么命令,但是不实际执行,可以用来检查makefile执行的步骤
//CMMI 安装, 即Configure、Make、Make Install
 
//编译的程序运行完直接退出了,可以在
main()的return前加一个
scanf("%c");
等用户输入字符后再退出。
//gcc开启调试:需要有-g选项,同时,不能有-s选项( -s Remove all symbol table and relocation information from the executable.).
//使用#error 时需要注意会导致编译终止:
#error "aaa" 会导致停止编译,并编译时报错aaa
#warning "aaa" 不会导致停止编译,并编译时告警aaa
 
//linaro和codesourcery都是支持linux工具链的公司
//#pragma pack来改变编译器的对齐方式,比如:
#pragma pack(n) /* 指定按n字节对齐 */
#pragma pack() /* 取消自定义字节对齐 */
 
//#pragma warning
该指令允许选择性地修改编译器警告信息。
例子:
#pragma warning( disable : 4507 34; once : 4385; error : 164 )
等价于:
#pragma warning(disable:4507 34) // 不显示4507和34号警告信息
#pragma warning(once:4385) // 4385号警告信息仅报告一次
#pragma warning(error:164) // 把164号警告信息作为一个错

//DEV-CPP中如何看内存,如下:

print /x &name[0]

获得内存地址:

执行:

x /32bc  0x62fe10

查询地址的内容

 

//Q:Dev-CPP中如何在debug时带入入参?

A:如下如果入参需要加一个 -help,则类似如下步骤操作,就进入 -help 分支了(使用的gdb的 "run 参数列表" 命令):

//嵌入式系统中gpio如果是输出pin,则先高/低电平,再配置方向,因为如果先配置方向,则有可能出现电平掉低又拉高,导致触发外围器件,比如CPLD芯片进入PROGRAM状态。

//有时为了查一个宏是否开启了,在代码中插入AAA或者BBB,但是如果是头文件查宏开关用AAA,BBB,编译报错的是某某C语言报错,比较难查,所以在头文件中推荐还是#error "AAA" 这种方式最佳。

// 数组赋值,采用如下的方式比较简洁:

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

struct  PPP
{
    char a;
    char b;
    char c;
};
    
int main(int argc, char *argv[]) {
int i ;
struct PPP kk[10] = {
    [0] = {0,0,0},
    [1] = {1,1,1},
    [3] = {3,3,3},
    [4] = {4,4,4},
    [9] = {20,20,20}
    };
    for(i =0;i<10;i++)
    {
        printf("[%d]-> %d \n",i, kk[i].a);
    }
  
    return 0;
}

显示结果:

 //看log时,经常需要分析一个函数(比如下面的at45dbx_chipselect_df())是具体被哪个函数调用的,如果每个地方都添加打印,就要修改n个地方,非常麻烦,其实可以通过修改这个函数,把调用者的行号打印出来,这样log中打印出来的行号(比如 “-->at45dbx_chipselect_df_2nd:line= 234”),快速甄别出是被哪个函数调用的。

修改前:

static void at45dbx_chipselect_df(U8 memidx, Bool bSelect)

{

xxxxx

}

修改后:

#define at45dbx_chipselect_df(a,b)   at45dbx_chipselect_df_2nd(a,b, __LINE__)

static void at45dbx_chipselect_df_2nd(U8 memidx, Bool bSelect , int line)

{

printf(“-->at45dbx_chipselect_df_2nd:line=%d” , line);

xxxxx

}

 

Linux软件开发

//看一个软件底层使用的哪些库的方法

 

 

其他

//防止控制时档位的波动性,比如风扇的PWM控制不同档位:
1.前后档位的阈值有一些重叠,避免乒乓切换
2.进入另一个档位, 需要2~3次取值都是一样的,才判断真正达到阈值,避免单个脉冲,就触发进入了另一个档位 
 
//从8bit到32bit的嵌入式纵览

本来想更新到维基百科,但是维基百科被封了,百度百科又不让更新词条,只能在自己的一亩地随便写写,列为看官欢迎指正:

----

CPU RTOS GUI 典型应用 小系统成本
8bit N N arduino等各种单片机开源/闭源项目 十元左右
8bit Y (比如keil C51的RTX51等) N   十元左右
8bit Y Y 按键输入,简单的LCD字符显示输出 几十元
32bit 不带显示驱动 Y(FreeRTOS,RT-Thread等非linux系统) N 如ESP8266(32-bit RISC microprocessor core based on the Tensilica Xtensa Diamond Standard 106Micro running at 80 MHz)使用的FreeRTOS 几十元
32bit 不带显示驱动 Y(嵌入式linux) N
如openWRT支持的诸多品牌路由器,如TP-LINK WR703N,Atheros的AR9331-AL1A处理器主频400MHz,使用busybox裁剪的shell。
如ArduinoYún使用Atmel ATmega32U4和附加的处理器Atheros AR9331 (CPU: MIPS 24Kc @400 MHz),该处理器运行Linux和OpenWrt无线堆栈
一百多元
32bit 带显示驱动 Y (android如各种手机或轻量级linux) Y 如Raspberry Pi4(博通 BCM2711 SoC,包含四个 1.5GHz Cortex A72 CPU 核心),BeagleBone(TI AM335x Arm Cortex-A8 1 GHz),有的是多核芯片

几百元

 

 

 

RT-Thread


//Q:  pkgs--update  和pkgs--upgrade  有什么区别呢?

A:
一个更新目录,一个更新具体package内容
前者更新当前项目引用的包到项目下的packages文件夹,后者更新本机的env文件夹下的软件包列表,它决定你的env菜单会出现哪些菜单项
update会下载包的源码,upgrade会下载包含包下载地址的json文件到env目录下的packages文件夹里,不会下载源码文件
 

 

posted on 2019-10-23 16:32  ni_sy  阅读(141)  评论(0编辑  收藏  举报