Kinetis-K40 FreeRTOS_V7.1.0移植学习记录
tziang@hotmail.com
摘要:IAR, Source insight, J-LINK, FreeRTOS
2012-3-6
参照FreeRTOS_V7.1.0中的K60
1.
复制CORTEX_Kinetis_K60_Tower_IAR并改名为CORTEX_Kinetis_K40X256_IAR;
打开工程,编译提示找不到很多头文件
工程选项中添加头文件路径
C/C++ compile / Preprocessor 中添加
$PROJ_DIR$ 代表工程文件(后缀为.eww文件)的当前目录
$PROJ_DIR$/../ 代表工程文件所在目录的上层目录,以此类推,增加相应的头文件路径即可
直到编译没有错误
Freescale_code/common/startup.c编译出错,在C/C++ compile / Preprocessor的Defined symbol
选项框中增加TWR_K60N512
最终Partest.c中的
GPIOA_PDDR=GPIO_PDDR_PDD( ulLEDs[ 0 ] | ulLEDs[ 1 ] | ulLEDs[ 2 ] | ulLEDs[ 3 ] );
编译不过,GPIOA_PDDR没定义,更新下,
增加\FreeRTOSV7.1.0\Demo\CORTEX_Kinetis_K40X256_IAR\Freescale_Code\cpu\headers
使用自己的头文件,而不是IAR系统自带的(\Freescale_Code\common\common.h中定义)
到此,官方发布的K60的模板没有问题了(或许官方的代码你直接编译就没有问题,可能是我的IAR6.10有问题,不过折腾下,也对IAR的使用有一些基本了解)
2.
开始修改为K40的模板
删除网络相关部分代码
修改\Freescale_Code\common\common.h,改成K40的配置
3.
将kinetis-K40的SLCD驱动增加到工程中
Main函数的prvSetupHardware()中增加SLCD的操作函数,试验OK.
到此,FreeRTOS的K40框架模板基本完成了。
下一步是将kinetis-K40 demo中的其它驱动移植过来,
在模板drivers目录下新建k40demodriver文件夹,将Freescale提供的Kwikstik_Demo驱动一一移植过来。
2012-3-7
1.
移植buzzer驱动,需要Driver_PIT.c中的中断使能和禁止函数,一并拷过来。
用到一个void _PIT0_Isr(void) 定时器0中断服务函数
在vectors.h中,增加对应的中断函数入口地址,默认的是default_isr,所以这边不改的话,会在vectors.c中的default_isr( )死循环;
Vectors.h中可以很清楚的看到只有几个用到的isr对应的中断向量入口函数,其余的都是default_isr,用户可以根据模板,在具体应用中增加相应的中断服务程序即可。
2.
移植ADC,DAC,FlexMem,FlexTimer,GPIO,SD,TSI,UART,
这几个驱动直接就可以编译通过了
3.
Electrodes,TSI移植也比较简单,增加Kwikstik_Demo中的另外一些头文件即可,
USB的比较麻烦,用到MXQ的一些库等等,暂时不搞;
到此,基本驱动差不多了。
现在来看一下整个系统从上电开始的运行过程
1.
ctr0.s ;初始化ARM的寄存器,跳转到start.c中
2.
start.c #禁止wdog,
#拷贝必要的中断向量或代码段到RAM中,这个函数跟具体的编译环境相关
#系统初始化,主要是初始化一些时钟,pll那边配置要根据实际的晶体修改下,
另外,这边还初始化了调试用的trace_clk_init(); fb_clk_init();以及调
试串口等,后面再确认能否省略。
#flash相关检查
#跳转到main函数
3.
main.c #执行prvSetupHardware( ) 即具体平台的初始化工作,比如移植驱动时的驱动测试
可以在这里进行;
#下面就是涉及FreeRTOS的创建一系列任务等操作。
# 最后是vTaskStartScheduler(),到此操作系统就已经跑起来了。
现在开始来驱动细化
SCLD里面有个_time_delay函数,应该是MXQ的,目前是改成减循环函数来替代的,准备增加个定时器1中断来实现延迟
参照Driver_buzzer.c的定时器0中断处理函数来写
增加Driver_delaymSec.c文件,vector.c vector.h中修改对应的PIT内容,Driver_PIT.c中PIT1开启,没有成功,可能是PIT1的设置和PIT0有细微差异,暂不搞吧,设置系统时钟为100MHz,重新定义个delayms函数给系统使用,明天开始看FreeRTOS的细节,先搞两个任务,SLCD显示和buzzer看能不能跑起来。
2012-3-12
关于source insight的一些设置
1.增加汇编语言的关键字彩色显示
Option->Document Options-> "C Source FIle"对应的File filter中加入 *.s
2.文件中高亮设置,关键字高亮设置便于后面查找
按SHIFT+F8
现在来整理一些FreeRTOS的基本知识,
1.目录结构
FreeRTOS
¦
+-Demo
¦ ¦
¦ +-Common 各种体系共用的文件
¦ +-Dir x 体系x的范例程序文件
¦ +-Dir y 体系y的范例程序文件
¦
+-Source
¦
+-Portable 特定处理器代码
+-include 头文件
2.命名规则
a.变量
char类型的变量以 c 为前缀
short类型的变量以 s 为前缀
long类型的变量以 l 为前缀
float类型的变量以 f 为前缀
double类型的变量以 d 为前缀
枚举变量以 e 为前缀
其他类型(如结构体)以 x 为前缀
指针有一个额外的前缀 p , 例如short类型的指针前缀为 ps
无符号类型的变量有一个额外的前缀 u , 例如无符号short类型的变量前缀为 us
b.函数
文件内部函数以prv为前缀
API函数以其返回值类型为前缀,按照前面对变量的定义
函数的名字以其所在的文件名开头。如vTaskDelete函数在Task.c文件中定义
c.数据类型
数据类型并不直接在RTOS内核内部引用。相反,每个平台都有其自身的定义方式。例如,char类型定义为portCHAR,short类型定义为portSHORT等。范例程序源代码使用的就是这种符号,但这并不是必须的,你可以在你的程序中使用任何你喜欢的符号。
此外,有两种额外的类型要为每种平台定义。分别是:
portTickType
可配置为16位的无符号类型或32位的无符号类型。参考API文档中的 定制部分获取详细信息。
portBASE_TYPE
为特定体系定义的最有效率的数据类型。
如果portBASE_TYPE定义为char则必须要特别小心的保证用来作为函数返回值的signed char可以为负数,用于指示错误。
3.基本框架
在主函数中,内核启动前至少要穿件一个任务
然后执行vTaskStartScheduler( void ) ,开始任务调度,vTaskStartScheduler( )执行后空闲任务自动被创建
在main.c中增加一个显示任务每隔1S显示一次
和uc/OS类似,简单步骤如下:
1.定义该任务的优先级;
2.main函数中增加任务
xTaskCreate( prvSLCDDisplayTask, #函数名
( signed char * ) "SLCD", #r任务名,便于调试
configMINIMAL_STACK_SIZE,#栈大小,words为单位
NULL,
mainSLCD_DISPLAY_TASK_PRIORITY,#优先级
NULL );
函数原型为
portBASE_TYPE xTaskCreate( pdTASK_CODE prvTaskCode,
const portCHAR * const pcName,
unsigned portSHORT usStackDepth,
void *prvParameters,
unsigned portBASE_TYPE uxPriority,
xTaskHandle *prvCreatedTask );
参数说明:
prvTaskCode |
指向任务的入口函数. 任务必须执行并且永不返回 (即:无限循环). |
pcName |
描述任务的名字。主要便于调试。最大长度由 configMAX_TASK_NAME_LEN.定义,包括'\0'结束符 |
usStackDepth |
指定任务堆栈的大小 ,堆栈能保护变量的数目- 不是字节数. 例如,如果堆栈为16位宽度,usStackDepth定义为 100, 200 字节,这些将分配给堆栈。堆栈嵌套深度(堆栈宽度)不能超多最大值——包含了size_t类型的变量 |
prvParameters |
指针用于作为一个参数传向创建的任务 |
uxPriority |
任务运行时的优先级 |
prvCreatedTask |
用于传递一个处理——引用创建的任务,比如删除,改变优先级等等,可以用vTaskDelete( xHandle ) 删除任务,比如 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); // 使用处理来删除任务. vTaskDelete( xHandle ); vTaskDelete(NULL),为删除当前任务
|
返回值:
pdPASS 是如果任务成功创建并且添加到就绪列中,另外错误代码在projdefs. H文件定义
3.定义prvSLCDDisplayTask函数
static void prvSLCDDisplayTask( void *pvParameters )
{
portTickType xLastWakeTime;
const portTickType xFrequency = 1000; //定义需要的频率
xLastWakeTime = xTaskGetTickCount(); //使用当前Tick初始化xLastWakeTime
for( ; ; )
{
vTaskDelayUntil( &xLastWakeTime, xFrequency );//精确延时
LCD_GCR ^= LCD_GCR_LCDEN_MASK; //切换SLCD显示
}
}
测试没有问题,可以正常运作,到此FreeRTOS V7.1.0在Kinetis-K40上移植的基本框架就此结束,可以此为模板进行进一步深入开发。
典型的任务函数结构
void ATaskFunction( void *pvParameters )
{
/* 可以像普通函数一样定义变量。用这个函数创建的每个任务实例都有一个属于自己的iVarialbleExample变量。但如果iVariableExample被定义为static,这一点则不成立 – 这种情况下只存在一个变量,所有的任务实例将会共享这个变量。 */
int iVariableExample = 0;
/* 任务通常实现在一个死循环中。 */
for( ;; )
{
/* 完成任务功能的代码将放在这里。 */
}
/* 如果任务的具体实现会跳出上面的死循环,则此任务必须在函数运行完之前删除。传入NULL参数表示删除的是当前任务 */
vTaskDelete( NULL );
}
2012-3-13
Acrobat 中F3快捷键为浏览下一个查找的字符串
参考资料:
1.K40P144M100SF2RM
2.http://www.freertos.org/
3.FreeRTOS中文资料;
4.KWIKSTIKDEMOSWLAB;
5.KWIKSTIK-K40-SCH_V4-原理图.
文章评论(0条评论)
登录后参与讨论