其实在单片机上也能使用类linux驱动模块框架module_init(init_fun),从而给驱动管理提供了新的方式。
boot.icf文件
- /*###ICF### Section handled by ICF editor, don't touch! ****/
- /*-Editor annotation file-*/
- /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
- /*-Specials-*/
- define symbol __ICFEDIT_intvec_start__ = 0x08000000;
- /*-Memory Regions-*/
- define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
- define symbol __ICFEDIT_region_ROM_end__ = 0x0807FFFF;
- define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
- define symbol __ICFEDIT_region_RAM_end__ = 0x2001FFFF;
- /*-Sizes-*/
- define symbol __ICFEDIT_size_cstack__ = 0x8000;
- define symbol __ICFEDIT_size_heap__ = 0x0000;
- /**** End of ICF editor section. ###ICF###*/
-
- define memory mem with size = 4G;
- define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
- define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
- define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
- define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-
- initialize by copy { readwrite };
- do not initialize { section .noinit };
-
- place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
- place in ROM_region { readonly, section mysection };
- place in RAM_region { readwrite,
- block CSTACK, block HEAP };
-
- export symbol __ICFEDIT_region_RAM_start__;
- export symbol __ICFEDIT_region_RAM_end__;
其实改icf文件很简单,就在 ROM区创建一个名为 “mysection ” 的段。
place in ROM_region { readonly, section mysection };
main.c
- #include <stdio.h>
-
- #pragma section="mysection"
- #define MODULE_BEGIN (__segment_begin("mysection"))
- #define MODULE_END (__segment_end("mysection"))
-
- typedef void (*init_function_t)(void);
- #define _init __attribute__((used, section("mysection")))
- #define MODULE_INIT(func) init_function_t _fn_##func @ "mysection" = func // 方法一
- //#define MODULE_INIT(func) init_function_t _fn_##func _init = func // 方法二
-
- void drv_spi_init (void)
- {
- printf("drv_spi_init...\n");
- }
- MODULE_INIT(drv_spi_init); //将函数放入 “mysection” 段
-
- void drv_uart_init (void)
- {
- printf("drv_uart_init...\n");
- }
- MODULE_INIT(drv_uart_init); //将函数放入 “mysection” 段
-
- void drv_i2c_init (void)
- {
- printf("drv_i2c_init...\n");
- }
- MODULE_INIT(drv_i2c_init); //将函数放入 “mysection” 段
-
- void do_initcall(void)
- {
- init_function_t *call = (init_function_t *)MODULE_BEGIN;
- init_function_t *end = (init_function_t *)MODULE_END;
-
- /* 逐个初始化驱动 */
- do
- {
- (*call)();
- call++;
- }while(call < end);
- }
-
-
- /*!
- \brief Boot main function
- \param[in] none
- \param[out] none
- \retval none
- */
- int main(void)
- {
- /* 驱动列表初始化 */
- do_initcall();
-
- /* user code */
- //...
-
- return 0;
- }
这样就可以在STM32等单片机上实现类linux风格的驱动管理了,同样的方法可以实现module_deinit。