Chinaunix首页 | 论坛 | 博客
  • 博客访问: 132249
  • 博文数量: 38
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 191
  • 用 户 组: 普通用户
  • 注册时间: 2016-06-16 11:31
个人简介

嵌入式新人

文章分类

全部博文(38)

文章存档

2016年(38)

我的朋友

分类: 嵌入式

2016-05-16 14:05:39

第一个ARM程序是在开发板上实现LED灯的闪烁,需要编写的程序有led.s,makefile和mkv210_image.c,使用make编译完成后,通过USB下载到开发板上,就可以看到灯的闪烁。
1.程序的编辑
在window的共享文件夹winshare/1.4/1.leds_s下编辑led.s,makefile和mkv210_image.c
1.1 start.S的内容

点击(此处)折叠或打开

  1. .global _start

  2. _start:
  3.     // 设置GPJ0CON的bit[12:23],配置GPJ0_3/4/5引脚为输出功能
  4.     ldr r1, =0xE0200240     //0xE0200240是寄存器GPJ0CON的地址                
  5.     ldr r0, =0x00111000
  6.     str r0, [r1]

  7.     
  8.     
  9. led_blink:
  10.     // 设置GPJ0DAT的bit[3:5],使GPJ0_3/4/5引脚输出低电平,LED亮
  11.     ldr r1, =0xE0200244     //0xE0200244是寄存器GPJ0DAT的地址                
  12.     mov r0, #0
  13.     str r0, [r1]

  14.     // 延时
  15.     bl delay             //bl是带返回的跳转,常用于函数调用。在跳转之前,将下一条指令的地址拷贝到R14(LR,链接寄存器),返回时使用指令“mov pc, lr”即可实现返回。                

  16.     // 设置GPJ0DAT的bit[3:5],使GPJ0_3/4/5引脚输出高电平,LED灭
  17.     ldr r1, =0xE0200244                     
  18.     mov r0, #0x38
  19.     str r0, [r1]

  20.     // 延时
  21.     bl delay    
  22.     
  23.     //mov r2, #0x1000
  24.     //sub r2, r2, #1
  25.     //cmp r2,#0
  26.     //bne led_blink
  27.     b led_blink

  28. halt:
  29.     b halt //b是跳转指令,跳转到指定的地址执行程序


  30. delay:
  31.     mov r0, #0x900000
  32. delay_loop:
  33.     cmp r0, #0
  34.     sub r0, r0, #1
  35.     bne delay_loop
  36.     mov pc, lr

1.2makefile的内容

点击(此处)折叠或打开

  1. led.bin: start.o
  2.     arm-linux-ld -Ttext 0x0 -o led.elf $^
  3.     arm-linux-objcopy -O binary led.elf led.bin
  4.     arm-linux-objdump -D led.elf > led_elf.dis
  5.     gcc mkv210_image.c -o mkx210
  6.     ./mkx210 led.bin 210.bin
  7. # $^ 代表所有依赖文件

  8. %.o : %.S
  9.     arm-linux-gcc -o $@ $< -c
  10. # $@ 目标文件,$<代表第一个依赖文件

  11. %.o : %.c
  12.     arm-linux-gcc -o $@ $< -c

  13. clean:
  14.     rm *.o *.elf *.bin *.dis mkx210 -f
1.3 mkv210_image.c的内容

点击(此处)折叠或打开

  1. /*
  2.  * mkv210_image.c的作用是为BL1添加header information(包括BL1 size和Checksum)
  3.  *
  4.  * 本文件来自于友善之臂+朱有鹏的裸机教程。
  5.  */
  6. /* 在BL0阶段,iROM内固化的代码读取启动介质eSSD,NAND,one NAND,NORFlash或SD/MMC前16K的内容,
  7.  * 并比对前16字节中的校验和是否正确,正确则继续,错误则停止;UART/USB启动不需要BL1的header information。
  8.  */
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <stdlib.h>

  12. #define BUFSIZE (16*1024)
  13. #define IMG_SIZE (16*1024)
  14. #define SPL_HEADER_SIZE 16
  15. //#define SPL_HEADER "S5PC110 HEADER "
  16. #define SPL_HEADER "****************"

  17. int main (int argc, char *argv[]) //从外面传递参数到main函数
  18. {
  19.     FILE        *fp;
  20.     char        *Buf, *a;
  21.     int        BufLen;
  22.     int        nbytes, fileLen;
  23.     unsigned int    checksum, count;
  24.     int        i;
  25.     
  26.     // 1. 3个参数
  27.     if (argc != 3)
  28.     {
  29.         printf("Usage: %s \n", argv[0]);
  30.         return -1;
  31.     }

  32.     // 2. 分配16K的buffer
  33.     BufLen = BUFSIZE;
  34.     Buf = (char *)malloc(BufLen);
  35.     if (!Buf)
  36.     {
  37.         printf("Alloc buffer failed!\n");
  38.         return -1;
  39.     }

  40.     memset(Buf, 0x00, BufLen);

  41.     // 3. 读源bin到buffer
  42.     // 3.1 打开源bin
  43.     fp = fopen(argv[1], "rb");
  44.     if( fp == NULL)
  45.     {
  46.         printf("source file open error\n");
  47.         free(Buf);
  48.         return -1;
  49.     }
  50.     // 3.2 获取源bin长度
  51.     fseek(fp, 0L, SEEK_END);                                // 定位到文件尾
  52.     fileLen = ftell(fp);                                    // 得到文件长度
  53.     fseek(fp, 0L, SEEK_SET);                                // 再次定位到文件头
  54.     // 3.3 源bin长度不得超过16K-16byte
  55.     count = (fileLen < (IMG_SIZE - SPL_HEADER_SIZE))
  56.         ? fileLen : (IMG_SIZE - SPL_HEADER_SIZE);
  57.     // 3.4 buffer[0~15]存放"S5PC110 HEADER "
  58.     memcpy(&Buf[0], SPL_HEADER, SPL_HEADER_SIZE);
  59.     // 3.5 读源bin到buffer[16]
  60.     nbytes = fread(Buf + SPL_HEADER_SIZE, 1, count, fp);
  61.     if ( nbytes != count )
  62.     {
  63.         printf("source file read error\n");
  64.         free(Buf);
  65.         fclose(fp);
  66.         return -1;
  67.     }
  68.     fclose(fp);

  69.     // 4. 计算校验和
  70.      // 4.1 从第16byte开始计算,把buffer中所有的字节数据加和起来得到的结果
  71.     a = Buf + SPL_HEADER_SIZE;
  72.     for(i = 0, checksum = 0; i < IMG_SIZE - SPL_HEADER_SIZE; i++)
  73.         checksum += (0x000000FF) & *a++;
  74.     // 4.2 将校验和保存在buffer[8~15]
  75.     a = Buf + 8;                            
  76.     *( (unsigned int *)a ) = checksum;

  77.     // 5. 拷贝buffer中的内容到目的bin
  78.     // 5.1 打开目的bin
  79.     fp = fopen(argv[2], "wb");
  80.     if (fp == NULL)
  81.     {
  82.         printf("destination file open error\n");
  83.         free(Buf);
  84.         return -1;
  85.     }
  86.     // 5.2 将16k的buffer拷贝到目的bin中
  87.     a = Buf;
  88.     nbytes    = fwrite( a, 1, BufLen, fp);
  89.     if ( nbytes != BufLen )
  90.     {
  91.         printf("destination file write error\n");
  92.         free(Buf);
  93.         fclose(fp);
  94.         return -1;
  95.     }

  96.     free(Buf);
  97.     fclose(fp);

  98.     return 0;
  99. }
2 程序的编译
在linux中转到winshare/1.4/1.leds_s下,然后运行make命令,完成程序的编译。



3 程序的下载
在Win7中运行DNW(需要长按开机键),通过USB将编译完成后的led.bin下载到开发板上,可以观察到3个LED灯在闪烁
阅读(1827) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~