1.串口:
串口类型: 针串口 、usb串口的使用
1. usb 串口 插入电脑,计算机上设备管理器中其他设备下出现新设备
设备管理器 中查看
2. 安装串口驱动 ,安装驱动以后 系统分配com4 串口
3. windows下载串口连接软件 MobaXterm,连接串口,进入linux
2.jtag烧写口:(和rk的烧写工具一个原理,速度很慢,开发时候推荐用下面的usb下载烧写)
针口(开发板10针口),需要排线连接板子和eop
usb烧写器有哪些: jlink(付费的 )、op、 eop(jz2440标配)
eop功能: 1. 烧程序 2. usb 转串口功能
1. 排线连接 板子上10针口和 eop ,eop 连接电脑 usb
2 . eop 驱动 安装
问题: widnows驱动签名,禁止签名,解决,Windows7 win10 系统如何强制禁用驱动程序签名 - Kooapk - 博客园
选择 D:\softpackage\weidongshagn\OpenJTAG 安装,需要安装 3 次 ,安装成功如下图
windows 安装 烧写软件
安装目录下带有oflash.exe
运行oflash 命令
烧裸板程序 leds.bin 到 NandFlash
NorFlash : 可以烧 uboot
NandFlash : 可以烧 裸板程序\uboot
可以从 Nor 或者 Nand启动, 开发板子上 有 开关
完成以后断开排线、 eop 从电脑上取下来 ,设置为nand , 启动波动开关,重新上电重启
烧uboot u-boot.bin 到 Nor Flash
完成以后断开排线 , 设置为nor启动 拨动开关, 重新上电 ,串口会输出倒计数,在0来之前 ,在串口中 输入空格 ,进入uboot 选项 ,如果不按 空格键, 那么会进入 默认linux 系统
3 . usb devices :
原理:windows通过 DNW 软件通过usb 传输文件到 uboot, uboot具备usb下载功能, 在烧到nandflash中
优点 : 通过usb devices 传递传递文件到ubtoot, 然后安装, 速度快 , jtag 比较慢
usb device 使用, 烧写 leds.bin 到 Nand Flash
1. 把uboot 烧到 nor Flash , 拨打nor启动开关,打开串口工具, 上电, 按下空格 ,进入uboot 菜单选项
2. usb device 驱动安装:
2.1. usb 线 连接 设备与电脑 ,电脑上出现新设备
2.2. 安装驱动程序 : F:\工具和驱动\USB DNW
启动 zadig-2.3.exe , 点击 Options/List All Devices
3. 在串口 工具输入 [n] Download u-boot to Nand Flash n 、 下载程序到Nand Flash
n 表示 接收 usb 文件 并烧 写到 nand flash, 如果看不到这个菜单,输入menu
使用 dnw_100ask.exe 从 windows 传递文件到 开发板
DNW 选择 USD Port- Transmit 发送文件,选择文件leds,bin , 看串口工具平台, 烧写成功
uboot 收到文件, lends.bin 安装成功,在烧到nand Flash 中
设置 nand 启动,重新上电,运行 裸机程序
再次看到 leds.bin 闪烁效果 ,是3个灯光交替闪烁
4、 souce Insight使用
配置: Options -> Document Options -> C Source File -> 加上*.c;*.h;*.S
SoucecInsight导入源码 :
1、 Project -- New Project -- 填入项目名称、 项目目录 【这里填写的是索引目录名称】
2、 选择导入源码位置, shift 全选, Add
project - rebuild project : 解析项目种的宏定义、 函数、变量等调用关系, 从而可以快速查找这些内容
那么就可以查看导入的源码了
双击: Untitled Project.PR 那么可以打开项目
然后进行 : Add and Remove Project Files 可以添加新文件,删除导入 的文件
3. Option-> Document Options -> Sreen Fonts -> 宋体(常规) 脚本(选择gb2312)
4. source insight 的窗口:
(右) 项目窗口: 项目中有哪些文件
中
左
下
在View 中可以打开关闭对应窗口
5. 显示行号:
View - > line number
6. 快速跳转到某一行:
Search - go to line
7. 高亮关键字 :
选项一个 关键词 Count ,鼠标右键, 高亮关键词,所有的Count 都会高亮
8. 查看函数定义:
双击函数: 可以在上下文窗口看到函数定义的源代码
按下ctrl+ 点击函数 调入函数
如何退回去:
9. 搜索:
ctrl + / 点击以后下面有显示 , 大小写忽略 这些
4 . 点亮 LED ,嵌入式入门
4.1. 理论基础:
点亮led:
芯片->引脚 输出高 电、低点
芯片可以跑程序,不需要系统
芯片与控制外界的方式通过引脚 引脚可以是GPIO | 可以是串口
进制:
二进制: 001 0001 0001 2进制和10进制转化 8421法
八进制: 00 100 010 001 3位一组
0 4 2 1
16进制: 1 1 1 4位一组
c中进制定义: int a= 0421 8进制
int a= 0x60 16进制
把 bit 7,8 置1
int b = 0x123 | (1<<7) | (1 <<8) = 0x577
把 bit 7,8 清除
int b = 0x123 & (1<<7) & (1 <<8) = 0x23
ubuntu 编译 32位可执行文件:
-m32 无法编译,安装 libc6库环境:
sudo apt-get update
sudo apt-get purge libc6-dev
sudo apt-get install libc6-dev
sudo apt-get install libc6-dev-i386
gcc -m32 -o hello.o hello.c : 32 为平台下,指针占4个字节
gcc -o hello.o hello.c : 64 位平台下,指针 8个字节
c 不同平台运行:
windows x86
ubuntu x86 : gcc编译
arm 裸机: arm-linux-gcc->烧写->运行
预编译->编译->汇编->链接
链接:
汇编生成obj文件 .o文件
系统库生成obj文件: 比如crt1.o、crti.o 、crtbegin.o 系统标准启动文件,一般应用程序是必须的
链接libc库文件: libc 库文件就是实现printf等函数
链接静态库,直接拷贝, 程序会变大
链接动态库, 运行时动态加载 ,程序不会变大
gcc -c -o hello.o hello.c
gcc -v -nostdlib -o hello hello.o: 会提示没有链接标准启动文件和标准库文件,链接失败
-nostdlib 这个选项常用于 裸机/bootloader、linux 内核等程序, 它们不需要启动文件、标准库文件
** Ubuntu 18 安装arm-linux-gcc交叉编译
出现问题:
错误1:
arm-linux-gcc -c -o led_on.o led_on.S
/opt/FriendlyARM/toolschain/4.4.3/libexec/gcc/arm-none-linux-gnueabi/4.4.3/cc1: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory
安装: sudo apt-get install lib32stdc++6
了解一下寄存器:
2440 寄存器分布:
cpu 的寄存器 有R1 R2 R3 R15 , 可以直接访问
GPIO 寄存器 , 有 GPFCON (配置寄存器) GPFDAT (控制寄存器) , 以地址访问
常用arm 指令:
为了实现上面功能,学习几天简单汇编指令
LDR : 读内存 , LDR R0, [R1] : 读取R1 地址上数据保存到R0中
STR : 写内存 , STR R0,[R1] : 把 R0 的值 写到 地址 R1
bl : 跳转
bl main 跳到main函数,返回地址保存到lr 寄存器里面,返回地址就是下一条指令地址
MOV: MOV R0 , R1 把 R1 的值 赋值 给 R0
MOV R0,#0x100 R0=0x100
LDR R0,=0x12345678 : R0 = 0x123454678;
伪指令: 并不存在这种指令,会被拆分 几条指令
add : 加法
add r0,r1,#4 : r0 = r1+4
sub : 减法
sub r0, r1,#4 r0 = r1 - 4
sub r0, r1,r2 r0 = r1 - r2
ldb 【出栈】 stm【入栈】:
ldm: 都内存写入多个寄存器
// 处理完成开始恢复现场,其实就是做中断返回,关键是将r0-r12,pc,cpsr一起回复
ldmfd sp!, {r0-r12, pc}^
例子:
stmdb sp!,{fp,ip,lr,pc}
先减后存(存高地址) , 比如此时sp指向 4096, 首先sp-4 , 存高地址,pc=r15, pc存进去
ldmia
ldmia sp,{fp,sp,pc} 首先读取后增加
首先读取sp指向的栈地址内容fp, sp=sp+4 移动sp , 出栈
! 含义:
30000524: e8bc000f ldmia ip!, {r0, r1, r2, r3} // 读30000708 上的数据,SDRAM 上的就是
// sdRAM 没有数据,还没有初始化,必死无疑去读取 ,所以 不可以访问有初始值的数组 位置无关代码
! 作用就是r0的值在ldm过程中发生增加或者减少写回到r0中去, r0的值会改变,上面r0不会改变
-如上读取ip内存地址的值,读取4个字节连续,读了以后ip地址的值改变
stm :
// 保存r0-r12和lr到irq模式下的栈上面
stmfd sp!, {r0-r12, lr}
总结:
ldm 出栈, 读取连续内存的值 , 对应c的 int b = *p;
stm 入栈, 写入连续内存的值, 对应c的 *p= 100;
对应入栈,出栈 【 不同参数含义,首先移动pc 或者sp指针还是 首先放入一个字节数据 】
【韦 - arm画图理解】
编译汇编源码: led_on.S
/*
* 点亮LED2: gpf5
*/
.text
.global _start
_start:
/* 配置GPF5为输出引脚
* 把0x400写到地址0x56000050
*/
ldr r1, =0x56000050
ldr r0, =0x400 /* mov r0, #0x400 */
str r0, [r1]
/* 设置GPF5输出高电平
* 把0写到地址0x56000054
*/
ldr r1, =0x56000054
ldr r0, =0 /* mov r0, #0 */
str r0, [r1]
/* 死循环 */
halt:
b halt
arm-linux-gcc -c -o led_on.o led_on.S
arm-linux-ld -Ttext 0 led_on.o -o led_on.elf
arm-linux-objcopy -O binary -S led_on.elf led_on.bin
使用oflash烧录到 nandFlash中,断电、断开排序、设置nand启动,重新上电,效果如图所示: