ecos代码分析(4)
下面开始看cyg_start()
< redboot/v3_0/src/main.c>
void cyg_start(void)
:: an no parameters routine
è CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version)
:: hal_virtual_vector_table[14]= RedBoot_version
:: RedBoot_version是一个表示redboot版本信息的字符数组
è CYGACC_CALL_IF_MONITOR_RETURN_SET(return_to_redboot)
:: hal_virtual_vector_table[21]= return_to_redboot
:: return_to_redboot大概是用来进程切换的,不确定,以后有调用到再分析,这里只是设置
è diag_init_putc(_mon_write_char)
:: _putc = _mon_write_char
è hal_if_diag_init()
:: 只会被调用一次
è CYGACC_CALL_IF_SET_CONSOLE_COMM()
:: hal_virtual_vector_table[13]= set_console_comm()
:: CYGNUM_CALL_IF_SET_COMM_ID_MANGLER = -3
è set_console_comm(-3)
è CYGACC_CALL_IF_CONSOLE_PROCS_SET(comm_channels[0])
:: comm_channels是个二维数组,smdk2410来说comm_channels[3][8]
:: 设置hal_virtual_vector_table [5]=comm_channels[0]
è CYGACC_CALL_IF_SET_CONSOLE_COMM(-1)
è set_console_comm(-1)
:: 获取当前comm号,注意这里的static int __selected_id是个静态的,所以返回0
è CYGACC_CALL_IF_SET_CONSOLE_COMM\
(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL)
:: CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL = 0
è set_console_comm(0)
:: __selected_id = 1
:: 设置hal_virtual_vector_table [5]=comm_channels[1]
:: ram_start = 0x0
:: ram_end = 0x4000000即64M
:: workspace_start = 0x0
:: workspace_end = 0x4000000
:: workspace_end_init = workspace_end = 0x4000000
:: entry_address = 0xffffffff for Nothing has ever been loaded into memory
è bist()
:: build in self test, it is null
:: 运行__RedBoot_INIT_TAB__到__RedBoot_INIT_TAB_END__之间的所有函数
< redboot/v3_0/src/main.c>
320 for (init_entry = __RedBoot_INIT_TAB__; init_entry != &__RedBoot_INIT_TAB_END__; init_entry++) {
321 (*init_entry->fun)();
322 }
详细说明一下
CYG_HAL_TABLE_BEGIN( __RedBoot_INIT_TAB__, RedBoot_inits );
CYG_HAL_TABLE_END( __RedBoot_INIT_TAB_END__, RedBoot_inits );
65 #define __string(_x) #_x
66 #define __xstring(_x) __string(_x)
67
69 #define CYG_HAL_TABLE_BEGIN( _label, _name )
70 __asm__(".section \".ecos.table." __xstring(_name) ".begin\",\"aw\"\n" \
71 ".globl " __xstring(CYG_LABEL_DEFN(_label)) "\n" \
72 ".type " __xstring(CYG_LABEL_DEFN(_label)) ",object\n" \
73 ".p2align"__xstring(CYGARC_P2ALIGNMENT)"\n" \
74 __xstring(CYG_LABEL_DEFN(_label))":\n" \
75 ".previous\n" \
76 )
78
80 #define CYG_HAL_TABLE_END( _label, _name ) \
81 __asm__(".section \".ecos.table." __xstring(_name) ".finish\",\"aw\"\n" \
82 ".globl " __xstring(CYG_LABEL_DEFN(_label)) "\n" \
83 ".type " __xstring(CYG_LABEL_DEFN(_label)) ",object\n" \
84 ".p2align " __xstring(CYGARC_P2ALIGNMENT) "\n" \
85 __xstring(CYG_LABEL_DEFN(_label)) ":\n" \
86 ".previous\n" \
87 )
#define CYG_LABEL_DEFN(_name_) _name_
扩展后如下:
#define CYG_HAL_TABLE_BEGIN( _label, _name )
.section ".ecos.table.RedBoot_inits.begin","aw"
.globl __RedBoot_INIT_TAB__
.type __RedBoot_INIT_TAB__ ,object
.p2align 5
__RedBoot_INIT_TAB__ :
.previous
.section ".ecos.table.RedBoot_inits.finish","aw"
.globl __RedBoot_INIT_TAB_END__
.type __RedBoot_INIT_TAB_END__ ,object
.p2align 5
__RedBoot_INIT_TAB_END__ :
.previous
又有
typedef void void_fun(void);
typedef void_fun *void_fun_ptr;
struct init_tab_entry {
void_fun_ptr fun;
} CYG_HAL_TABLE_TYPE;
#define _RedBoot_init(_f_,_p_) \
struct init_tab_entry _init_tab_##_p_##_f_ \
CYG_HAL_TABLE_QUALIFIED_ENTRY(RedBoot_inits,_p_##_f_) = { _f_ };
#define RedBoot_init(_f_,_p_) _RedBoot_init(_f_,_p_)
#define CYG_HAL_TABLE_QUALIFIED_ENTRY( _name, _qual ) \
CYGBLD_ATTRIB_SECTION(".ecos.table." __xstring(_name) ".data." \
__xstring(_qual)) \
CYGBLD_ATTRIB_USED
# define CYGBLD_ATTRIB_SECTION(__sect__) __attribute__((section (__sect__)))
说明运行RedBoot_init(_f_,_p_)时会把代码放到segment
.ecos.table. RedBoot_inits.data. _p_##_f_ 里面
查找RedBoot_init,结果如下:
Decompress.c (redboot\v3_0\src):RedBoot_init(_zlib_init, RedBoot_INIT_FIRST);
Fconfig.c (redboot\v3_0\src):RedBoot_init(load_flash_config, RedBoot_INIT_SECOND);
Flash.c (redboot\v3_0\src):RedBoot_init(_do_flash_init, RedBoot_INIT_FIRST);
Flash_load.c (redboot\v3_0\src):RedBoot_init(flash_load_init, RedBoot_INIT_LAST);
Ide.c (redboot\v3_0\src\fs):RedBoot_init(ide_init, RedBoot_INIT_FIRST);
Net_io.c (redboot\v3_0\src\net):RedBoot_init(net_init, RedBoot_INIT_NET);
RedBoot_init(ide_init, RedBoot_INIT_FIRST)就表示ide_init代码存放在segment:
.ecos.table. RedBoot_inits.data. 0000ide_init 里面
:: 这里有初始化ide flash net zlib,这些初始化函数以后再看了
:: mem_segments[0].start = workspace_start;
:: mem_segments[0].end = workspace_end;
è cyg_plf_redboot_startup()
:: Run a platform specific startup function
è do_version(0,0)
:: redboot正式启动,打印一大堆东西,有版本 内存信息 flash信息等等
è diag_printf()
è _vprintf()
:: 一大堆字符的格式化处理,然后调用_putc输出
:: _putc = _mon_write_char这是前面赋值的,现在运行了,所以要看看了
è static void _mon_write_char(char c, void **param)
è void mon_write_char(unsigned char c)
è CYGACC_CALL_IF_SET_CONSOLE_COMM(-1)
:: 查询当前用到的com赋值给cur
:: CYGACC_CALL_IF_SET_CONSOLE_COMM(i),设com_i为console
:: __chan = CYGACC_CALL_IF_CONSOLE_PROCS()获取要输出的channel
:: CYGACC_COMM_IF_PUTC(*__chan, c) 输出字符
è cyg_hal_plf_serial_putc() 串口初始化时指定hal_diag.c中
:: 只要串口的FIFO没有满,就往里面写,串口输出
è CYGACC_CALL_IF_SET_CONSOLE_COMM(cur)设回cur_com
è int _rb_gets(char *buf, int buflen, int timeout)
:: 从输入获取指令(字符串)
è int _rb_gets_preloaded(char *buf, int buflen, int timeout)
è mon_set_read_char_timeout()
:: 设置读取字符的timeout
è cyg_hal_plf_serial_control()
:: 设置chan->msec_timeout
è mon_read_char_with_timeout()
è CYGACC_COMM_IF_GETC_TIMEOUT()
è cyg_hal_plf_serial_getc_timeout()
è cyg_hal_plf_serial_getc_nonblock()
:: 直接读取字符,非阻塞
è CYGACC_CALL_IF_DELAY_US(100)
è delay_us()
:: 从寄存器TCNTO4直接读取时间量
è mon_read_char()
:: 获取输入字符串,无时限
:: 将得到的字符组合起来到buf中,返回
è struct cmd *cmd_search(struct cmd *tab, struct cmd *tabend, char *arg)
è struct cmd *cmd_search(struct cmd *tab, struct cmd *tabend, char *arg)
:: 从__RedBoot_CMD_TAB__到__RedBoot_CMD_TAB_END__搜索
:: 同前面的初始化segment一样,不多说了
:: 用函数RedBoot_cmd实现对命令的声明
此后就开始执行所输入命令