ARM:Makefile作成、リンクスクリプト作成、裸板shellフレームワーク
11213 ワード
『Makefile作成、リンクスクリプト作成、裸板shellフレームワーク』
'ツール:UtraEditコード編集ツール
//このツールのCtrl+h ASCIIコードの表示
vi中コマンドモード:
':e main.c//mainを開く.c
':bn//さっきのに戻ります.cファイル
1.rについての質問
Windowsシステムでは:
r行ヘッダ0 x 0 dに戻る
次の行0 x 0 aへ
linuxシステムでは、1文字しか必要ありません.
hexdump -C 1.txt //1.txtで車をノックバック
一、Makefileについて-//調べれば勉強しなくてもいい
1) env\GNU make v3.80完全版中国語ガイドpdf
2)私と一緒にMakefileを書く
makefileは主に3つの部分に分かれています.
ターゲットファイル[target]:依存ファイル[dependencies][1 Tab]ルール
'makeとmakefileの役割:
makeツールは、大規模なソフトウェアのコンパイルを管理するために使用されます.
-プログラムのどのファイルがコンパイルされる必要があるかを自動的に判断し、コマンドでコンパイル操作を実行することができる.
-類似の統合開発環境(IDE)の自動化コンパイルを実現する.
makefileは、次のルールを定義します.
-どのファイルを先にコンパイルする必要があるのか、どのファイルを後でコンパイルする必要があるのか、より複雑な機能操作を再コンパイルする必要があるのか.-makefileでオペレーティングシステムのコマンドを実行できます
現段階で目標を達成する:
一番簡単なMakefileを書くことができます.
$:'vi Makefile
'$<依存ファイルを表します
'$@はターゲットファイルを表します
二、リンクスクリプトについて
【リンク】
-複数の入力ファイル(.o file)を一定のルールに従って1つの出力ファイルにマージします.
-住所は?半句
【リンクスクリプト】
-接続ツールの入力ファイル;
-リンクスクリプトには独自の構文があります.
'リンクスクリプトの役割:
1)主に入力ファイル内のSECTIONを出力ファイル内に入れる方法を規定するために用いられる.2)出力ファイル内の各部分のプログラムアドレス空間内のレイアウトを制御する;
リンクスクリプトファイル
$:'vi shell.lds
'C言語ポインタ復習【メモリに注目】
三、shellフレームワークを作成する
自己検証の補足:
'ツール:UtraEditコード編集ツール
//このツールのCtrl+h ASCIIコードの表示
vi中コマンドモード:
':e main.c//mainを開く.c
':bn//さっきのに戻ります.cファイル
1.rについての質問
Windowsシステムでは:
r行ヘッダ0 x 0 dに戻る
次の行0 x 0 aへ
linuxシステムでは、1文字しか必要ありません.
hexdump -C 1.txt //1.txtで車をノックバック
一、Makefileについて-//調べれば勉強しなくてもいい
1) env\GNU make v3.80完全版中国語ガイドpdf
2)私と一緒にMakefileを書く
makefileは主に3つの部分に分かれています.
ターゲットファイル[target]:依存ファイル[dependencies][1 Tab]ルール
'makeとmakefileの役割:
makeツールは、大規模なソフトウェアのコンパイルを管理するために使用されます.
-プログラムのどのファイルがコンパイルされる必要があるかを自動的に判断し、コマンドでコンパイル操作を実行することができる.
-類似の統合開発環境(IDE)の自動化コンパイルを実現する.
makefileは、次のルールを定義します.
-どのファイルを先にコンパイルする必要があるのか、どのファイルを後でコンパイルする必要があるのか、より複雑な機能操作を再コンパイルする必要があるのか.-makefileでオペレーティングシステムのコマンドを実行できます
現段階で目標を達成する:
一番簡単なMakefileを書くことができます.
$:'vi Makefile
'$<依存ファイルを表します
'$@はターゲットファイルを表します
/** - Makefile **/
NAME=shell
ELF=$(NAME).elf #shell.elf
BIN=$(NAME).bin #shell.bin
OBJS=main.o uart.o
CC=arm-cortex_a9-linux-gnueabi-gcc
LD=arm-cortex_a9-linux-gnueabi-ld
OBJCOPY=arm-cortex_a9-linux-gnueabi-objcopy
CFLAGS=-nostdlib -Wall
LDFLAGS=-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 ...
二、リンクスクリプトについて
【リンク】
-複数の入力ファイル(.o file)を一定のルールに従って1つの出力ファイルにマージします.
-住所は?半句
【リンクスクリプト】
-接続ツールの入力ファイル;
-リンクスクリプトには独自の構文があります.
'リンクスクリプトの役割:
1)主に入力ファイル内のSECTIONを出力ファイル内に入れる方法を規定するために用いられる.2)出力ファイル内の各部分のプログラムアドレス空間内のレイアウトを制御する;
リンクスクリプトファイル
$:'vi shell.lds
/** - shell.lds **/
ENTRY (main) // -emain
SECTIONS {
. = 0x48000000; // .text
.text : { //
main.o (.text) // main.o
* (.text)
}
.data : { //
* (.data)
}
.bss : { // BSS
* (.bss)
}
}
// ,Makefile :
$(ELF):$(OBJS)
$(LD) $(LDFLAGS) -Tshell.lds $(OBJS) -o $(ELF)
'C言語ポインタ復習【メモリに注目】
char s1;
char* s2;
char s3[10];
char* s4[10];
s1 = 'a';
s2 = 'b'; // ,
s2 = "12345";
s2++;
(*s2)++; // 【 】,12345 , , !
strcpy (s2, "hello"); // 【 】,(readonly) 。
s3[0] = 'c';
s3[0] += 1;
s3++; // 【 】 , , ( )
strcpy (s3, "world");
/** - **/
#include
#include
int main (void) {
char* s1 = "hello";
char* s2 = s1; // 【 】s2 -
strcpy (s2, "world..");
printf ("s2 = %s
", s2); // !
return 0;
}
/** **/
:
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
/** - 、typedf、 **/
#include
int add (int x, int y) {
printf ("Enter add func...
");
return x + y;
}
// pFunc
// 4
//
typedef int (*pFunc) (int, int);
int main (void) {
int res = 0;
// res = add (1, 2);
// pfunc1
// ,bit32-4
// 4 1
//
int (*pfunc1) (int, int);
pfunc1 = add; // ,
res = pfunc1 (10, 20);
printf ("res = %d
", res); // 30
// ---------- typedef -----------
pFunc pfunc2;
pfunc2 = add;
res = pfunc2 (100, 200);
printf ("res = %d
", res); // 300
//
res = (*((int (*) (int, int))0x0000000000400544)) (1000, 2000);
printf ("res = %d
", res); // 3000
return 0;
}
三、shellフレームワークを作成する
/** - main.c **/
/* include , extern 。
#include "uart.h"
#include "led.h"
#include "beep.h"
#include "mystrcmp.h"
*/
#define CMD_MAX_LED 32
char 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 ("
myArmShell#: ");
//
uart_gets (cmd_buf, CMD_MAX_LED);
if (! mystrcmp (cmd_buf, "ledon")) {
led_on ();
uart_puts ("
ledon success...");
}
if (! mystrcmp (cmd_buf, "ledoff")) {
led_off ();
uart_puts ("
ledoff success...");
}
if (! mystrcmp (cmd_buf, "beepon")) {
beep_on ();
uart_puts ("
beepon success...");
}
if (! mystrcmp (cmd_buf, "beepoff")) {
beep_off ();
uart_puts ("
beepoff 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 ) Function1
GPIOD_ALTFN0 &= ~(3 << 28); // GPIOD14
GPIOD_ALTFN0 |= (1 << 28);
GPIOD_ALTFN1 &= ~(3 << 4); // GPIOD18
GPIOD_ALTFN1 |= (1 << 4);
// : PLL[1] 800MHz
UART0CLKGEN0L &= ~(7 << 2);
UART0CLKGEN0L |= (1 << 2);
// 800/(0x0f+1)=50MHz
UART0CLKGEN0L &= ~(0xff << 5); // [12:5] 8
UART0CLKGEN0L |= (0xf << 5); // [12:5] 4 1111
// UART
ULCON0 = 0x03; // 8N1
UCON0 = 0x05; // 0101 == 0x05 polling
UFCON0 |= (3 << 1); // FIFO, 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 == '
')
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 ,
}
void uart_gets (char* buf, int len) {
int i = 0;
char tmp = 0;
while (i < len - 1) {
tmp = uart_getc ();
// , ?
uart_putc (tmp);
buf[i] = tmp;
if (tmp == '\r')
break;
i++;
}
//
buf[i] = '\0';
}
/** - mystrcmp.h **/
#ifndef _MYSTRCMP_H
#define _MYSTRCMP_H
int 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_H
extern 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) {
// 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);
//
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);
}
自己検証の補足:
"extern - "
// add.h
#ifndef _ADD_H
#define _ADD_H
extern int add (int, int);
#endif //_ADD_H
// add.c
int add (int x, int y) {
return x + y;
}
// main.c
#include
int main (void) {
int i = 10;
int j = 20;
int sum = add (i, j);
printf ("sum = %d
", sum);
return 0;
}
" static - "
// , : , : 。
#include
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; :
printf ("&s is : %p
", &s); // 0x601020
printf ("s is : %d
", s); // 1
return &s;
}
int main (void) {
int* p_num = add1 (10, 20); // s is : 1
printf ("p_num is : %p
", p_num); // 0x601020
printf ("*p_num is : %d
", *p_num); // 1
*p_num = 2;
add1 (11, 22); // s is : 2
// printf ("&sum is : %p", &sum); // sum
return 0;
}