1. 问: 我去别的城市工作要换手机号怎么办?
答: 更换手机号,单独联系 班主任 处理。
2. 问: 今天是文字直播?/现在有视频直播吗?
答: 碰到疑难问题,才会用视频直播。今天应该不会有视频直播。
3. 问: 单片机的裸机课预计上几次课?
答: 裸机课程3、4次课。
4. 问: 学这个课程是不是需要把单片机基础看一遍呢?
答: 不用,RTOS重在软件,单片机操作不多;后面会讲ARM架构。
5. 问: 如果遇到当晚培训没空,看回课后资料,应该没什么区别跟错过的东西吧?
答: 就是缺了互动,其他没区别。
6. 问: 为啥程序都是从0x80000000开始?
答: 在这节课只是假设的一个地址。
7. 问: stm系列代码运行在片上flash吗?
答: 我们假设它在Flash上运行,讲到ARM架构时可以让程序在RAM里运行。
8. 问: CPU如何访问Flash、RAM、GPIO这些内存或外设?
答: CPU大爷使用不同的地址,访问RAM,GPIO,FLASH。从这个角度看,GPIO、RAM、Flash地位相同。
a. RAM的特性就是:写什么进去,读出来仍然是什么。
b. Flash的特性就是:不能轻易写数据进去,可以读。
c. GPIO的特性就是:写数据进去有特殊的含义,可能是让引脚变为高电平、低电平。
这几个儿子,功能都不一样。但是在大爷眼里,都是儿子,都有地址,都是使用地址来访问的。
9. 问: 地址可以随便写吗,比方说写地址0?
答: 这个地址存在对应的设备才可以,就想7个葫芦娃,你想使唤第8个,那是不存在的。也就是说,访问的地址必须是芯片规定给的地址范围才可以。你写一个地址,涉及芯片时,这个地址没有设备:写它的话,就没有任何作用。
10. 问: a=123
这个怎么看是写内存的地址?地址是123吗?写到哪里去了?
答: a是变量,变量可读可写,只能在RAM里。123
是要写入的值,地址在链接程序时分配的,要查看分配的是哪个地址可以运行的时候调试查看。
11. 问: “Flash的特性就是:不能轻易写数据进去,可以读” 不太理解
答: 我们开发程序时,烧写程序,就是烧写到Flash上,断电后,Flash的内容也不会丢失,Flash上存的是程序,很宝贵,无法简单地写数据进去,必须经过特殊步骤:比如擦除后才能写,比如写的时候要先解锁。如果Flash能轻易写数据进去,你的程序就很容易被破坏。
12. 问: 前面例程的变量a和p在flash烧录文件里也是以地址+数据形式存在吗,这里的“地址”可以自定义分配吗?
答: a = 123; p =xxx;
在Flash中是这样保存的:假设编译器给a、p分配的地址分别是addr1, addr2。a = 123; 变成几条汇编指令,如下:
MOV R0, ADDR1
MOV R1, #123
STR R1, [R0]
看不懂汇编没关系,ARM架构里会讲。翻译一下:
a = 123;
变成几条汇编指令:
- 把addr1的值放进CPU的内部寄存器R0;
- 把123的值放进CPU的内部寄存器R1;
- 把R1的值写到一个地址上去,哪个地址?R0里就是地址值;
关键的地方来了:a = 123
:
- 把123这个数,写到变量a去,就是写addr1对应的内存;
- 在汇编码中,隐含有了addr, 隐含有了123;
- 执行完汇编指令,来自Flash的数值123,被写到了内存addr1 地方;
13. 问:p = (volatile unsigned int *)(0x40010800 + 0x0c)
中的volatile unsigned in
可以不写吗?
答: 可以不写,会有警告。
14. 问: cpu不是将flash数据读取到RAM中,在RAM中执行吗?还可以直接读gpio地址吗?
答: 这是不对的。CPU是把Flash的数据,读入CPU内部,在CPU内部执行。对RAM的访问只有2种:读、写。
看这个 a = a + b:
- 从内存读a,存入CPU;
- 从内存读b,存入CPU;
- CPU内部:val = a + b;
- 把val写到内存a处;
- 对于内存RAM,只有读、写操作;对于Flash,在这里只有读操作,CPU从Flash上读到执行,在CPU内部执行指令:
15. 问: 内存管理器需要配置各个外设的地址范围吗?或者说可以配置吗?需要配置吗?
答:
- 一般无法配置;
- 无论是103,还是其他芯片比如IMX6ULL,芯片手册都会有一章:memory map,里面讲的就是,芯片上各个设备的地址范围;
16. 问: 变量和数据是分开在两片区域存储的 ?
答:
-
变量a,地址为
0x20000000
,链接程序时就确定了,程序运行时它在内存里,注意是运行时; -
a=123
这是指令,指令里有数据123,它在Flash上; -
执行完
a=123
后,内存地址0x20000000
处的值就被写为123; -
123这个值,来自Flash,被传到了RAM
17. 问: 汇编里的寄存器,和GPIO这些寄存器有什么区别,是访问方式和地址不同么?
答:
寄存器,这个词取得很不好。CPU内部的寄存器,GPIO上的寄存器,完全不是一回事:
- CPU里面的寄存器,使用汇编指令来读写;
- GPIO上的寄存器,像内存一样,CPU发出地址信号、数据信号,来读写它;
18. 问: 这个传话人是我们编程写好吗?比如发地址给它,然后发出片选信号?
答: 芯片设计时,硬件就设计好了,软件无法更改。
19. 问: 地址长度为什么都是4?
答: ①首先,这里是有个前提的:是在32位的机器下。②这32位就限制了内存地址的长度只能是32位也即是4个字节,所以我们使用sizeof获得一个指针变量的长度时,就只能得到一个结果,那就是4个字节长度。③对于32位CPU,CPU大爷能发出32条地址线,所以地址的值,就是用32bit来表示。④各种变量大小不同,但是它的地址,准确地说首地址,都是32位的。⑤指针变量,用来保存地址,所以任何的指针变量,sizeof(XXX *)都是4字节,也就是32位。
20. 问: char buf[1000] ,没初始化,sizeof(buf)也是4吧?
答:是1000。没初始化的意思只是里面的值没设置,但是占用的空间CPU给你保留下来了。
21. 问:
ldr r0, =0x20000000
ldr r1, =123
str r1, [r0]
怎么判断是数据还是地址?
答: 前面无法判断是数据还是地址,用起来是才知道是数据还是地址。在第3条指令:STR R1, [R0]
这是一条写内存指令,R1是数据,R0是地址。如果你这样写:STR R0, [R1]
,那么 R0是数据,R1是地址。STR是store的意思。
22. 问: 能不能这样理解程序运行的过程:
程序存储在Flash中(待处理) CPU每次执行一句代码(处理一句代码),将每次执行的结果存储到RAM中(无论堆还是栈),如果需要就在RAM中提取数据(比如GPIOS-ODR寄存器)。
答: 结果不一定保存到RAM,比如:*p = 1;
p指向GPIO寄存器,那么这条指令就是 去写GPIO寄存器,结果是写到了GPIO去了。当然,p的值是来自RAM。“每次执行的结果存储到RAM中”: 错在“每次”
23. 问: arm指令集和thumb指令集都是32为寻址吗?
答: 是的。Flash上每条thumb指令时16位的,但是CPU去读Flash、读写RAM、读写GPIO时,发出的地址线是32位的。CPU得到了16位的指令,根据16位的指令:比如 STR R0, [R1]
, 它是把R1的32位数值发送到地址线去。所以thumb还是arm指令,并不影响寻址的地址线长度。
24. 问: 在Linux里运行自己写的程序,可以删除自己的可执行文件,为什么说单片机里的程序在Flash?
答: Linux是把程序读入RAM,然后运行;单片机也可以把Flash上的程序读入RAM运行,然后擦除Flash,只是单片机RAM没那么大,我们可以不把Flash上的代码复制到RAM。
25. 问: 提到首地址了,老师有时间可以讲一下pack指令吗?什么情况下需要使用对齐,如何使用:
struct {
char c;
int a;
};
答: 首先,这个结构体多大?按理说,char
是1字节,int
是4字节,所以这结构体是5字节。但是,如果这样分配空间的话,int a
的地址就是奇数,访问效率不高。所以,这个结构体对于char c
,仍然分配4字节,即使只用1字节。我们能否强制让它分配5字节?可以,用pack指令,具体用法可以百度搜索。
26. 问: cortex-m系列我可以理解为代码位于Flash上,变量位于RAM上吗?这样从Flash取指令速度会不会受限?这是cortex-m系列的特点吗?
答: 这样理解没什么问题。其实是可以将M系列Flash上的代码放到其RAM里去运行的,如果RAM空间足够的话。在Flash上速度确实会慢一点,基于成本考虑可以忍。
27. 问: FreeRTOS的任务堆栈一般是动态分配的吗?动态分配一般不会溢出的吧?
答: 动态分配更方便,但是一些追求极致稳定的系统不允许动态分配。
28. 问: 在32位将其中,结构体为什么分配四字节对齐访问效率会更高?
答: 首先看下这张图:
CPU去访问位宽为32的RAM时,硬件上一次读写是以32位为单位的,比如:即使读一个char c
,内存控制器也是去RAM上读到32位的数据就是4字节数据,把其中一字节返回给CPU。①对于上图的变量a,可以一次性读、写完;②对于上图的变量b,要读2次:第1次读得到下图椭圆中的4字节:
第2次读,得到下图椭圆中的4字节:
image.png
然后组合下图中的椭圆中的内容:
image.png
这样的操作有个什么问题呢?效率特别的低下,速度特别的慢!而且硬件还不一定支持这样寻址读取。
29. 问: 有个内存控制器用片选帮忙寻址相应设备,既然每个设备都有自己的固定的内存地址,为什么还要需要片选选中某个设备呢
答: 因为大家共享地址线、数据线,纯粹的通过地址线寻址CPU是无法区分找到的是谁家。
网友评论