基于MQX40创建并移植K10 BSP包的方法文档格式.docx
《基于MQX40创建并移植K10 BSP包的方法文档格式.docx》由会员分享,可在线阅读,更多相关《基于MQX40创建并移植K10 BSP包的方法文档格式.docx(18页珍藏版)》请在冰豆网上搜索。
图2.选择开发平台和相关的软件库
2.2生成BSP包
为了简化操作,这里只选择IAR的开发环境,而且只选择生成BSP,PSP以及MQX例程,然后点击GenerateMQXProjects,开始创建新的BSP代码,如图3所示。
图3点击生成BSP包的工程
接着在C:
\Freescale\Freescale_MQX_4_0\config\K10DN512目录中,找到刚才生成的针对IAR的BSP代码,使用IAR开发环境选择File->
Open->
Workspace,打开build_libs.eww工程。
如图4所示。
图4打开IARBSP工程
注意:
在打开此工程时会提示RTCS、MFS、USB等库是否要加载。
由于本文档只针对基本的BSP、PSP包进行移植,而且在图2中只勾选了这两项,所以这里可以忽略除BSP、PSP以外的MFS、RTCS、USB等包的加载,直接点击确认完成就可以了。
如果在实际应用中需要使用其他的包,需要将图2中相应的Libraries库和参考代码的选项勾选上,然后再进行代码生成即可。
3.BSP包代码的修改
在C:
\Freescale\Freescale_MQX_4_0\mqx\source\psp\cortex_m文件夹里的psp_cpudef.h文件中可以找到支持KinetisK10/K20/K30/K40/K50/K60/K70等相关芯片的PSP宏定义,例如支持K10DN512的宏定义为:
#definePSP_CPU_MK10DN512Z(PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4,PSP_CPU_GROUP_KINETIS_K1X,2))
同时在该文件中还可以找到所有Freescale指定PSP处理器支持包所支持内核的宏定义,如ColdFire,PPC,Cortex-A5,Cortex-A8等。
在本文中,我们创建的是针对K10DN512的BSP开发包,所以需要用上述的宏定义,将user_config.h文件中的MQX_CPU定义
#defineMQX_CPUPSP_CPU_MK60DN512Z
修改为:
#defineMQX_CPUPSP_CPU_MK10DN512Z
此时点击编译按钮会出现错误提示,如下图5所示。
图5.头文件错误
出现这个错误是由于在C:
\Freescale\Freescale_MQX_4_0\mqx\source\psp\cortex_m\kinetis.h中找不到头文件MK10DZ10.h,需要从以下的IAR安装目录中寻找:
C:
\ProgramFiles\IARSystems\EmbeddedWorkbench6.5\arm\inc\Freescale
然后将该文件拷贝到C:
\Freescale\Freescale_MQX_4_0\mqx\source\psp\cortex_m\cpu中进行编译。
编译仍有错误出现,如下图6所示。
这个错误主要是由于移植使用的是K60的BSP包,因此里面含有以太网ENET部分和USB部分的代码,而在K10芯片中是没有这些功能模块的,在IARIDEWorkspace工作台环境下,需要将外围I/O驱动(PeripheralIODrivers)中的ENET和USB等文件夹删除,同时将K10DN512BSPFiles文件夹中的init_usb.c和init_enet.c文件删除。
另外在K10DN512BSPFiles中,由于在MQX安装目录C:
\Freescale\Freescale_MQX_4_0\mqx\source\bsp\K10DN512文件下的init_gpio.c和bsp.h中初始化了ent和usb部分的,需要打开这两个文件,找到_bsp_ent_io_init和bsp_usb_io_init的代码部分,然后直接进行删除。
此时再进行编译,则应该没有错误出现了。
图6以太网及USB相关的文件编译错误
下一步需要修改的,是系统的时钟设置。
针对K60DN512,MQX默认的外部时钟是50MHz。
对于K20系列MQX默认的外部时钟是8MHz,如果目标板的时钟和默认的外部时钟不一样,则需要重新配置。
例如,如果这里选择25MHz的无源晶体作为外接时钟,那么就需要修改bsp_cm.h中的时钟设置,将CPU_XTAL_CLK_HZ的时钟修改为25MHz。
当然根据实际项目设计有时也需要配置不同的总线时钟频率,内核时钟频率等,可以参照如下的代码对bsp_cm.h中的宏定义进行相应的修改:
#defineCPU_BUS_CLK_HZ48000000U/*初始化总线时钟频率为48MHz*/
修改为
#defineCPU_BUS_CLK_HZ50000000U/*初始化总线时钟频率为50MHz*/
#defineCPU_CORE_CLK_HZ96000000U/*初始化内核、系统时钟频率为96MHz*/
#defineCPU_CORE_CLK_HZ100000000U/*初始化内核、系统时钟频率为100MHz*/
#defineCPU_CLOCK_CONFIG_NUMBER0x03U/*定义时钟配置的个数,时钟配置有0,1和2,共3种可以选择*/
#defineCPU_BUS_CLK_HZ_CLOCK_CONFIG048000000U/*在时钟配置0中的总线时钟频率为48MHz*/
#defineCPU_BUS_CLK_HZ_CLOCK_CONFIG050000000U/*在时钟配置0中的总线时钟频率为50MHz*/
#defineCPU_CORE_CLK_HZ_CLOCK_CONFIG096000000U/*在时钟配置0中的内核、系统时钟频率为96MHz*/
#defineCPU_CORE_CLK_HZ_CLOCK_CONFIG0100000000U/*在时钟配置0中的内核、系统时钟频率为100MHz*/
#defineCPU_XTAL_CLK_HZ50000000U/*外部晶体或者振荡器的时钟频率为50MHz*/
#defineCPU_XTAL_CLK_HZ25000000U/*外部晶体或者振荡器的时钟频率为25MHz*/
相应的,对于使用的时钟配置0或者1或者2也需要修改,如果目标配置使用的是时钟配置0,可以参照如下代码修改。
如果不使用时钟配置1或者2,则不需要做修改。
/*在时钟配置0中的CPU时钟频率*/
#defineCPU_CLOCK_CONFIG_00x00U/*时钟配置0的定义*/
修改内核时钟频率,默认的是96MHz,改为100MHz。
#defineCPU_CORE_CLK_HZ_CONFIG_0100000000UL/*内核时钟频率为100MHz*/
修改总线时钟频率,默认是48MHz,修改为50MHz。
#defineCPU_BUS_CLK_HZ_CONFIG_050000000UL/*总线时钟频率为50MHz*/
修改Flash时钟频率,默认是24MHz,修改为25MHz。
#defineCPU_FLASH_CLK_HZ_CONFIG_025000000UL/*FLASH时钟频率为25MHz*/
#defineCPU_PLL_FLL_CLK_HZ_CONFIG_0100000000UL/*PLL/FLL时钟频率为100MHz*/
#defineCPU_OSCER_CLK_HZ_CONFIG_050000000UL
/*在时钟配置0中的系统OSC外部参考时钟*/
手工书写代码相对繁琐,更方便的方法是使用Freescale的ProcessorExpert工具,根据硬件的需要来设置时钟,生成的如下的代码。
通过PE工具来对CPU和各种外设进行设置,只需了解它的原理和用法,而不用把精力花在了解寄存器的具体细节上。
打开PE后,参照图7的配置进行设置,点击Project->
GeneratorProcessorExpertCode即可生成代码。
记住重新修改配置后需要点击Project->
Clean,清掉上次生成的代码,然后再执行生成代码的操作。
void__pe_initialize_hardware(void)
{
_bsp_watchdog_disable();
/*关闭WDOG模块*/
WDOG_UNLOCK=WDOG_UNLOCK_WDOGUNLOCK(0xC520);
WDOG_UNLOCK=WDOG_UNLOCK_WDOGUNLOCK(0xD928);
WDOG_STCTRLH=WDOG_STCTRLH_STNDBYEN_MASK|WDOG_STCTRLH_WAITEN_MASK|WDOG_STCTRLH_STOPEN_MASK|WDOG_STCTRLH_ALLOWUPDATE_MASK|WDOG_STCTRLH_CLKSRC_MASK;
/*系统时钟初始化*/
/*SIM_SCGC5:
PORTA=1*/
SIM_SCGC5|=SIM_SCGC5_PORTA_MASK
SIM_CLKDIV1=SIM_CLKDIV1_OUTDIV2(0x01)|SIM_CLKDIV1_OUTDIV3(0x03)|
SIM_CLKDIV1_OUTDIV4(0x03);
/*更新系统预分频器*/
SIM_SOPT1&
=(uint32_t)~(uint32_t)(SIM_SOPT1_OSC32KSEL_MASK);
PORTA_PCR18&
=(uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK|PORT_PCR_MUX(0x07)));
PORTA_PCR19&
/*切换到FBE模式*/
OSC_CR=OSC_CR_ERCLKEN_MASK;
SIM_SOPT2&
=(uint32_t)~(uint32_t)(SIM_SOPT2_MCGCLKSEL_MASK);
MCG_C2=(MCG_C2_RANGE(0x02)|MCG_C2_EREFS_MASK);
MCG_C1=(MCG_C1_CLKS(0x02)|MCG_C1_FRDIV(0x05)|MCG_C1_IRCLKEN_MASK);
MCG_C4&
=(uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK|MCG_C4_DRST_DRS(0x03)));
MCG_C5=MCG_C5_PRDIV(0x07);
MCG_C6=MCG_C6_VDIV(0x08);
while((MCG_S&
MCG_S_OSCINIT_MASK)==0x00U){/*判断晶振是否运行?
*/
}
MCG_S_IREFST_MASK)!
=0x00U){
/*判断FLL参考源是否为外部参考时钟*/
0x0CU)!
=0x08U){//等待,直到外部参考时钟作为MCG的输出
/*切换到PBE模式*/
MCG_C6=(MCG_C6_PLLS_MASK|MCG_C6_VDIV(0x08));
=0x08U){/*等待,直到外部参考时钟作为MCG输出*/
MCG_S_LOCK_MASK)==0x00U){/*等待直到锁住*/
/*切换到PEE模式*/
MCG_C1=(MCG_C1_FRDIV(0x05)|MCG_C1_IRCLKEN_MASK);
=0x0CU){/*等待,直到PLL输出*/
}
图7.PE设置
MQX4.0中PE的时钟初始化代码在bsp_cm.c文件的void__pe_initialize_hardware(void)函数中。
可以将上述PE生成的代码直接粘贴在该文件中。
调试可能会出现系统时钟配置错误。
当出现此类错误时,程序可能会停在图8所示的dispatch.s文件中的等待中断的语句cpsid.ni处。
这种错误往往是由于只修改了部分的时钟寄存器设置或者是直接使用其他系列的Kinetis的BSP包中的时钟配置,而没有做相应的修改所造成的。
例如,直接使用K60BSP包的默认时钟部分代码,在K10的25Mhz外部时钟环境中进行调试就会出现上述错误。
这里不建议手工书写代码或者直接拷贝其他Kinetis系列的不同时钟配置的代码,建议使用PE来配置生成时钟代码,对于有错误的部分PE中会有相关的红色提示符标示出来,因此不用担心那些时钟寄存器配置错误或被遗漏了。
图8.dispatch.s代码
一般地,在user_config.h配置中,RTC是默认使能的,也就是外部的32.768Khz晶振是需要外接的,如果不外接,可以将配置文件user_config.h中的宏定义语句:
#defineBSPCFG_ENABLE_RTCDEV1修改为
#defineBSPCFG_ENABLE_RTCDEV0
另外由于K10中不包含USB和以太网的代码,所以需要将相关的USB,Ethernet的文件删除,并将user_config.h头文件中的宏定义修改为:
#defineRTCSCFG_ENABLE_ICMP0
#defineRTCSCFG_ENABLE_UDP0
#defineRTCSCFG_ENABLE_TCP0
#defineRTCSCFG_ENABLE_STATS0
#defineRTCSCFG_ENABLE_GATEWAYS0
#defineFTPDCFG_USES_MFS0
#defineRTCSCFG_ENABLE_SNMP0
#defineTELNETDCFG_NOWAITFALSE
#defineHTTPDCFG_POLL_MODE0
#defineHTTPDCFG_STATIC_TASKS0
#defineHTTPDCFG_DYNAMIC_TASKS0
4.BSP包代码的调试
4.1.创建一个简单任务并运行
为了证明所创建的BSP是可以正常工作的,这里建一个最简单的IAR的工程,如图9所示,它包含了我们所创建的基于MQX4.0的K10DN512的BSP库。
图9建立一个IAR工程
选择保存工程的文件目录位置如下:
\Freescale\Freescale_MQX_4_0\demo\K10DN512Demo。
在main.c中添加如下的代码:
#include
#defineMAIN_TASK15
#defineSTACK_SIZE1024
#defineMAIN_STACKSTACK_SIZE
externvoidmain_task(uint_32);
extern"
C"
constTASK_TEMPLATE_STRUCTMQX_template_list[]=
{
//TaskIndex,Function,Stack,Priority,Name,Attributes,Param,TimeSlice*/
{MAIN_TASK,main_task,MAIN_STACK,11,"
main_task"
MQX_AUTO_START_TASK,0,0},
{0}
};
voidmain_task(uint_32parameter)
while
(1)
{
puts("
A"
);
}
需要将C:
\Freescale\Freescale_MQX_4_0\lib\K10DN512.iar\debug\bsp中的bsp.a库文件,以及C:
\Freescale\Freescale_MQX_4_0\lib\K10DN512.iar\debug\psp中的psp.a库文件添加到工程中去。
如下图10所示,点击main选择右键optionfornode“main”,并在C/C++Compiler的预处理器preprocessor和Assembler中设置文件的路径如下。
\Freescale\Freescale_MQX_4_0\lib\K10DN512.iar\debug\bsp
\Freescale\Freescale_MQX_4_0\lib\K10DN512.iar\debug\psp
\Freescale\Freescale_MQX_4_0\lib\K10DN512.iar\debug\bsp\Generated_Code
\Freescale\Freescale_MQX_4_0\lib\K10DN512.iar\debug
图10.在Option选项中设置
注意需要将
文件拷贝到C:
\Freescale\Freescale_MQX_4_0\lib\K10DN512.iar\debug\psp文件夹中。
编译完成后,通过JLINK等烧写工具将软件下载到目标板后开始运行,系统运行的界面如图11所示。
如果系统进不了main函数,说明MQXbsp系统移植还有问题,需要按照前面介绍的步骤进行仔细的检查。
图11复位后运行进入main函数
系统进入main函数,在mqx函数处设置断点,点击图标go运行,程序进入mqx初始化部分,如图12所示。
图12mqx初始化
在main_task中设置断点,再次运行,如图13所示,在IAR的JLINK任务栏中可以找到TASKLIST列表。
这里需要注意的是,需要在IAR的环境下,将option下debug插件的MQX勾选,如图14所示,勾选后才可以看到MQX的TASK等任务信息。
图13主任务运行
图14选取MQX
4.2GPIO配置与任务调试
在MQX4.0安装目录C:
\Freescale\Freescale_MQX_4_0\mqx\examples下可以找到很多参考例程,包括ADC、Hello、I2C、Lowpower、Timer等。
这里采用使用的最多的GPIO例程来验证BSP是否能正常工作。
由于在默认的bsp包中user_config.h中没有配置使能BSPCFG_ENABLE_GPIODEV外设,需要在该文件中加入语句#defineBSPCFG_ENABLE_GPIODEV1,如下图15所示。
图15使能GPIO任务配置
在这里,为了验证MQX4.0版本操作系统对于MQX3.8等早期版本软件代码的兼容性,本例使用的源程序
代码,可以在MQX3.8版本的安装目录中C:
\Freescale\FreescaleMQX3.8\mqx\examples\gpio找到。
直接将该文件添加到工程中,如图16所示,在IAR的主程序中,在读IO状态处设置断点,系统执行到此断点处,如果开启IAR任务栏的TASKList,在StackUageSummary窗口可以看到任务和