【分享】Kinetis-K40FreeRTOS_V7.1.0移植学习记录——转帖

2020-02-21 21:23发布

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.0DemoCORTEX_Kinetis_K40X256_IARFreescale_Codecpuheaders
使用自己的头文件,而不是IAR系统自带的(Freescale_Codecommoncommon.h中定义)
到此,官方发布的K60的模板没有问题了(或许官方的代码你直接编译就没有问题,可能是我的IAR6.10有问题,不过折腾下,也对IAR的使用有一些基本了解)
2.
开始修改为K40的模板
删除网络相关部分代码
修改Freescale_Codecommoncommon.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看能不能跑起来。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
18条回答
cn_x
1楼-- · 2020-02-22 03:10
2012-3-12
关于source insight的一些设置
1.增加汇编语言的关键字彩 {MOD}显示
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.定义,包括''结束符
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文件定义
cn_x
2楼-- · 2020-02-22 04:39
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-原理图.
sdlibin007
3楼-- · 2020-02-22 09:47
楼主这到处搞资料,不累么??
cn_x
4楼-- · 2020-02-22 10:23
sdlibin007 发表于 2014-8-26 10:54
楼主这到处搞资料,不累么??

上午没心情,就整资料玩
搞完了,不发了
一直觉得kinetis的资料很少
认真的搜索一下还是很多的
我昨天和今天找到的所有资料加在一起应该足够入门了
完成手头的活就开始折腾了
abszy
5楼-- · 2020-02-22 13:59
sdlibin007 发表于 2014-8-26 10:54
楼主这到处搞资料,不累么??

呵呵  我也觉得   不过还得感谢楼主了
zndz410
6楼-- · 2020-02-22 19:07
 精彩回答 2  元偷偷看……

一周热门 更多>