国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

ARM:Makefile編寫、鏈接腳本編寫、裸板shell框架

2019-11-10 23:23:45
字體:
供稿:網(wǎng)友
《Makefile編寫、鏈接腳本編寫、裸板shell框架》<tlinux系統(tǒng)中,只需要一個(gè)字符:/nhexdump -C 1.txt    // 1.txt 里面敲回車一、關(guān)于Makefile - // 查著用即可不用學(xué)1) env/GNU make v3.80完整版中文指南.pdf2) 跟我一起寫Makefile(后補(bǔ)--->)makefile主要分為三部分:目標(biāo)文件[target]:依賴文件[dependencies]    [1個(gè)Tab]規(guī)則'make與makefile 的作用:make工具用來管理大型軟件的編譯:- 自動(dòng)判斷一個(gè)程序的哪些文件需要編譯,并且能用命令來執(zhí)行編譯操作;- 實(shí)現(xiàn)類似集成開發(fā)環(huán)境(IDE)自動(dòng)化編譯;makefile定義了一系列的規(guī)則來指定:- 哪些文件需要先編譯,哪些文件需要后編譯,哪些文件需要重新編譯更復(fù)雜的功能操作。- makefile中可以執(zhí)行操作系統(tǒng)的命令現(xiàn)階段達(dá)標(biāo):可以寫最簡(jiǎn)單的Makefile。$:'vi Makefile' $< 代表依賴文件' $@ 代表目標(biāo)文件
/** 代碼演示 - Makefile **/NAME=shellELF=$(NAME).elf  #shell.elfBIN=$(NAME).bin  #shell.binOBJS=main.o uart.oCC=arm-cortex_a9-linux-gnueabi-gccLD=arm-cortex_a9-linux-gnueabi-ldOBJCOPY=arm-cortex_a9-linux-gnueabi-objcopyCFLAGS=-nostdlib -WallLDFLAGS=-nostdlib -nostartfiles$(BIN):$(ELF)         $(OBJCOPY) -O binary $(ELF) $(BIN)         cp $(BIN) /tftpboot/$(ELF):$(OBJS)         $(LD) $(LDFLAGS) -Ttext=0x48000000 -emain $(OBJS) -o $(ELF)%.o:%.c       $(CC) $(CFLAGS) -c $< -o $@clean:rm -rf $(BIN) $(ELF) $(OBJS) /tftpboot/$(BIN)// rm -vf ... 可以顯示刪除的文件列表提示信息二、關(guān)于鏈接腳本【鏈接器】- 將若干輸入文件(.o file) 根據(jù)一定規(guī)則合并為一個(gè)輸出文件;- 將標(biāo)號(hào)的地址??; // 半句話【鏈接腳本】- 連接工具的輸入文件;- 鏈接腳本有自己的語法;'鏈接腳本的作用:1) 主要用于規(guī)定如何把輸入文件內(nèi)的SECTION放入輸出文件內(nèi);2) 控制輸出文件內(nèi)各部分在程序地址空間內(nèi)的布局;鏈接腳本文件$:'vi shell.lds
/** 代碼演示 - shell.lds **/ENTRY (main)  // -emainSECTIONS {    . = 0x48000000;  // 指定 .text的起始位置    .text : { // 代碼段        main.o (.text)  // 可執(zhí)行文件以main.o最先鏈接        * (.text)    }       .data : { // 數(shù)據(jù)段        * (.data)    }       .bss : { // BSS堆        * (.bss)    }}// 寫完鏈接腳本文件后,Makefile 文件中對(duì)應(yīng)可修改此句:$(ELF):$(OBJS)        $(LD) $(LDFLAGS) -Tshell.lds $(OBJS) -o $(ELF)' C語言指針復(fù)習(xí)【關(guān)注內(nèi)存】
char s1;char* s2;char s3[10];char* s4[10];s1 = 'a';s2 = 'b'; // 不合理,警告s2 = "12345";s2++;(*s2)++; // 【段錯(cuò)誤】,12345是常量,在只讀代碼段,自增段錯(cuò)誤!strcpy (s2, "hello"); // 【段錯(cuò)誤】,(readonly)非法寫入。s3[0] = 'c';s3[0] += 1;s3++; // 【錯(cuò)誤】數(shù)組首地址,是地址常量,自增編譯不通過(非左值)strcpy (s3, "world");
/** 特例演示 - 指針 **/#include <stdio.h>#include <string.h>int main (void) {    char* s1 = "hello";    char* s2 = s1;  // 【內(nèi)存】s2 在代碼段 - 只讀常量區(qū)    strcpy (s2, "world..");    PRintf ("s2 = %s/n", s2); // 段錯(cuò)誤!    return 0;}
/** 函數(shù)指針 **/方法一:int (*pfunc1) (int, int);pfunc1 = add;pfunc1 (1, 2); // 3方法二:typedef int (*PFUNC) (int, int);PFUNC pfunc2 = add;pfunc2 (10, 20); // 30方法三: // 最難的用法(*((int (*) (int, int))0x0000000000400544)) (1000, 2000);  // 3000/** 代碼演示 - 函數(shù)指針、typedf、函數(shù)常地址 **/#include <stdio.h>int add (int x, int y) {    printf ("Enter add func.../n");    return x + y;}// 聲明一個(gè)指針變量pFunc// 該4字節(jié)存儲(chǔ)函數(shù)的地址// 存 <返回值是int,參數(shù)為int,int類型的函數(shù)地址>typedef int (*pFunc) (int, int);int main (void) {    int res = 0;    // res = add (1, 2); 正常調(diào)用    // 定義一個(gè)指針變量pfunc1    // 這個(gè)變量是個(gè)指針,bit32-4字節(jié)    // 該4字節(jié)存儲(chǔ)1個(gè)函數(shù)的地址    // 存 <返回值是int,參數(shù)為int,int類型的函數(shù)地址>    int (*pfunc1) (int, int);    pfunc1 = add; // 函數(shù)名和數(shù)組名一樣,可以代表其首地址    res = pfunc1 (10, 20);    printf ("res = %d/n", res); // 30    // ---------- typedef -----------    pFunc pfunc2;    pfunc2 = add;    res = pfunc2 (100, 200);    printf ("res = %d/n", res); // 300    // 函數(shù)指針最難的用法    res = (*((int (*) (int, int))0x0000000000400544)) (1000, 2000);    printf ("res = %d/n", res); // 3000    return 0;}三、編寫一個(gè)shell框架
/** 代碼演示 - 主函數(shù) main.c **//* 不需要寫 include ,關(guān)鍵字 extern 可以實(shí)現(xiàn)跨文件使用函數(shù)。#include "uart.h"#include "led.h"#include "beep.h"#include "mystrcmp.h"*/#define CMD_MAX_LED 32char cmd_buf[CMD_MAX_LED];int main (void) {    // 8N1 115200 non-FIFO polling    uart_init (); // uart 串口初始化    led_init (); // led 初始化    beep_init (); // beep 初始化    while (1) {        // 輸出命令提示符        uart_puts ("/nmyArmShell#: ");        // 接收用戶輸入的數(shù)據(jù)        uart_gets (cmd_buf, CMD_MAX_LED);        if (! mystrcmp (cmd_buf, "ledon")) {            led_on ();             uart_puts ("/nledon success...");        }           if (! mystrcmp (cmd_buf, "ledoff")) {            led_off ();             uart_puts ("/nledoff success...");        }           if (! mystrcmp (cmd_buf, "beepon")) {            beep_on ();             uart_puts ("/nbeepon success...");        }           if (! mystrcmp (cmd_buf, "beepoff")) {            beep_off ();             uart_puts ("/nbeepoff success...");        }       }       return 0;}
/** 代碼演示 - uart.h **/#ifndef _UART_H_#define _UART_H_extern void uart_init (void);extern void uart_puts (char*);extern void uart_gets (char*, int);#endif //_UART_H_/** 代碼演示 - uart.c **/#define UART0CLKENB     *((volatile unsigned int*)0xc00a9000)#define UART0CLKGEN0L   *((volatile unsigned int*)0xc00a9004)#define GPIOD_ALTFN0    *((volatile unsigned int*)0xc001d020)#define GPIOD_ALTFN1    *((volatile unsigned int*)0xc001d024)#define GPIOD_PULLENB   *((volatile unsigned int*)0xc001d060)#define ULCON0          *((volatile unsigned int*)0xc00a1000)#define UCON0           *((volatile unsigned int*)0xc00a1004)#define UFCON0          *((volatile unsigned int*)0xc00a1008)#define UTRSTAT0        *((volatile unsigned int*)0xc00a1010)#define UTXH0           *((volatile unsigned int*)0xc00a1020)#define URXH0           *((volatile unsigned int*)0xc00a1024)#define UBRDIV0         *((volatile unsigned int*)0xc00a1028)#define UFRACVAL0       *((volatile unsigned int*)0xc00a102c)void uart_init (void) {    /* uart0 clk disable */    UART0CLKENB &= ~(1 << 2);     // GPIOD18(Tx 接收管腳) GPIOD14(Rx 發(fā)送管腳) 配置功能Function1    GPIOD_ALTFN0 &= ~(3 << 28); // GPIOD14    GPIOD_ALTFN0 |= (1 << 28);    GPIOD_ALTFN1 &= ~(3 << 4); // GPIOD18    GPIOD_ALTFN1 |= (1 << 4);     // 時(shí)鐘配置:選擇PLL[1] 800MHz    UART0CLKGEN0L &= ~(7 << 2);     UART0CLKGEN0L |= (1 << 2);     // 分頻設(shè)置 800/(0x0f+1)=50MHz    UART0CLKGEN0L &= ~(0xff << 5); // [12:5] 8個(gè)位    UART0CLKGEN0L |= (0xf << 5); // [12:5] 4個(gè)位設(shè)置為1111    // UART控制器設(shè)置    ULCON0  = 0x03; // 8N1    UCON0   = 0x05; // 0101 == 0x05 polling    UFCON0 |= (3 << 1); // 清空FIFO,解決開發(fā)板命令行下運(yùn)行有多余字符的bug     UFCON0 &= ~(1 << 0); // non-FIFO disable    UBRDIV0 = 26; // 50000000/(115200*16) - 1 == 26.13    UFRACVAL0 = 2; // 0.13*16 == 2.08    /* uart0 clk enable */    UART0CLKENB |= (1 << 2); }void uart_putc (char c) {    // UTRSTAT0 bit[1] == 1, 緩存寄存器為empty    // 輪詢是否為空    while (! (UTRSTAT0 & 0x02)); // 分析?    UTXH0 = c;    if (c == '/n')        uart_putc ('/r');}void uart_puts (char* str) {    if (! str)        return ;    while (*str) {        uart_putc (*str);        str++;    }   }char uart_getc (void) {    // 輪詢 polling UTRSTAT0 bit[0] = 1 received data    while (! (UTRSTAT0 & 0x01));    return (char)(URXH0 & 0xff); // 只取低8位,是有效數(shù)據(jù)}void uart_gets (char* buf, int len) {    int i = 0;    char tmp = 0;    while (i < len - 1) {        tmp = uart_getc ();         // 回顯,注釋掉該句驗(yàn)證效果?        uart_putc (tmp);        buf[i] = tmp;        if (tmp == '/r')            break;        i++;    }       // 添加字符串結(jié)束標(biāo)志    buf[i] = '/0';}
/** 代碼演示 - mystrcmp.h **/#ifndef _MYSTRCMP_H#define _MYSTRCMP_Hint mystrcmp (const char*, const char*);#endif //_MYSTRCMP_H/** 代碼演示 - mystrcmp.c **/#include "mystrcmp.h"int mystrcmp (const char* s1, const char* s2) {    while (*s1) {        if (*s1 > *s2)            return 1;        else if (*s1 < *s2)            return -1;        s1++;        s2++;    }    return *s2 == 0 ? 0 : -1;}
/** 代碼演示 - led.h **/#ifndef _LED_H_#define _LED_Hextern void led_text (void);extern void led_on (void);extern void led_off (void);#endif // _LED_H/** 代碼演示 - led.c **/#define  GPIOC_OUT     *((volatile unsigned int*)0xc001c000)#define  GPIOC_OUTENB  *((volatile unsigned int*)0xc001c004)#define  GPIOC_ALTFN0  *((volatile unsigned int*)0xc001c020)void led_init (void) {    // 配置對(duì)應(yīng)管腳為GPIO功能    GPIOC_ALTFN0 &= ~ (3 << 24); // clear bit 24,25    GPIOC_ALTFN0 |= (1 << 24); // set bit 24    // 選擇為輸出功能    GPIOC_OUTENB |= (1 << 12); // OUTPUT}void led_on (void) {    GPIOC_OUT &= ~ (1 << 12); // clear bit 12}void led_off (void) {    GPIOC_OUT |= (1 << 12); // set bit 12}
/** 代碼演示 - beep.h **/#ifndef _BEEP_H_#define _BEEP_H_extern void beep_init (void);extern void beep_on (void);extern void beep_off (void);extern void delay (unsigned int);#endif //_BEEP_H_/** 代碼演示 - beep.c **/#define GPIOC_ALTFN0  *((volatile unsigned int*)0xc001c020)#define GPIOC_OUTENB  *((volatile unsigned int*)0xc001c004)#define GPIOC_OUT     *((volatile unsigned int*)0xc001c000)void beep_init (void) {    // 配置GPIO管腳    GPIOC_ALTFN0 &= ~(3 << 28);    GPIOC_ALTFN0 |= (1 << 28);    // 設(shè)置輸出功能    GPIOC_OUTENB |= (1 << 14);}void beep_on (void) {//    while (1) {  // 暫無法中斷,故先注銷        GPIOC_OUT |= (1 << 14); // 鳴叫 //        delay (10000000);//        GPIOC_OUT &= ~(1 << 14); // 不叫//        delay (10000000);//    }}void beep_off (void) {    GPIOC_OUT &= ~(1 << 14); }void delay (unsigned int n) {    while (--n);}自我驗(yàn)證補(bǔ)充:
"extern - 跨文件調(diào)用函數(shù) "// add.h#ifndef _ADD_H#define _ADD_Hextern int add (int, int);#endif //_ADD_H// add.cint add (int x, int y) {    return x + y;}// main.c#include <stdio.h>int main (void) {    int i = 10;     int j = 20;     int sum = add (i, j);     printf ("sum = %d/n", sum);    return 0;}
" static - 靜態(tài)局部變量 "// 數(shù)據(jù)段,作用域:當(dāng)前函數(shù),生命周期:整個(gè)當(dāng)前程序。#include <stdio.h>int add (int x, int y) {    static int sum;    return x + y;}int* add1 (int x, int y) {    static int s = 1; // static int s = x + y; 錯(cuò)誤:初始值設(shè)定元素不是常量    printf ("&s is : %p/n", &s); // 0x601020    printf ("s is : %d/n", s); // 1    return &s;}int main (void) {    int* p_num = add1 (10, 20); // s is : 1    printf ("p_num is : %p/n", p_num); // 0x601020    printf ("*p_num is : %d/n", *p_num); // 1    *p_num = 2;    add1 (11, 22); // s is : 2//  printf ("&sum is : %p", &sum); // sum 未聲明    return 0;}
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 会昌县| 洞头县| 香格里拉县| 财经| 辉南县| 阿拉善左旗| 饶阳县| 玉林市| 平泉县| 巴中市| 永清县| 民县| 綦江县| 灵台县| 青海省| 鹤庆县| 宾川县| 商河县| 康平县| 辽阳县| 汝州市| 新乐市| 大邑县| 土默特左旗| 滁州市| 丘北县| 色达县| 察隅县| 崇左市| 霍城县| 大化| 丰宁| 健康| 赞皇县| 毕节市| 金寨县| 秦安县| 望江县| 依安县| 永定县| 紫金县|