- 论坛徽章:
- 0
|
本帖最后由 fifodct 于 2011-01-14 10:31 编辑
想在Atmel AT9G20的平台上跑Linux 2.6.30. 开发板是SBC6020. 编译环境啥的基础工作应该都OK了,kernel下载到板子里,也能跑起来了。
现在在写主应用程序,由于里面需要频繁调用timer定时器, 我先写了个timer的测试程序。 相关源代码在附件里。
timer_test.rar
(8.67 KB, 下载次数: 30)
现在苦恼的是,对驱动模块编译时,总是出错。
后面三个error已经解决了,我在 /linux/miscdevice.h里 加上 #define irSIGNALRT4_MINOR 18 然后就ok了。
前面几个error还是不知道如何解决。 感觉/kernel/signal.c 里的函数没有被编译,或者没有被link过来. 反正是没什么头绪,不知道这边是否有高手能闪亮出现来解救我~~~
Thanks~~
源代码:
irsigrt4.c
/***********************************************************************
* irsigrt4.c module to generate SIGRT4 periodically
*
* This module is used to generat SIGRT4 signal periodically
* as timer base ticks every 50 ms to support up to 10 processes.
*
* This file entry is /dev/misc/irSIGRT4
* Two APIs: open and close
* open the file entry will start SIGRT4 generating for the process
* close the file entry will stop SIGRT4 generationg
*
* 6-1-2005 v0.2 change minor number to 18 and defined it in miscdevice.h instead of defined locally
*********************************************************************/
//#include <linux/config.h> /* custom configuration */
#include <linux/module.h> /* module_init */
#include <linux/init.h> /* __init */
#include <linux/signal.h>
#include <linux/miscdevice.h>
#include <linux/timer.h>
#include <linux/fs.h>
#define RT4_MINOR (irSIGNALRT4_MINOR)
#define VER "1.0 - 2.6.12"
#define DRIVER_NAME "SIGRT4 generator"
#define MAX_TASK (10) /* change needed based on multi-process system */
#define TIMER_CT (5) /* counts in jiffies to generate the signal */
#define SIGRT4 (SIGRTMIN+4)
//static unsigned int testingct;
// structure for each task
struct task_signal_t {
struct timer_list rt4_timer; // timer
struct task_struct *rt4_task; // current task
pid_t pid; // id
};
static struct task_signal_t tasks[MAX_TASK];
// timer service
static void rt4_timer_handler( unsigned long data)
{
#if 0
if( data == 0 ) // testing only for first task
{
if( ((++testingct) % 20) == 0 )
{
printk( KERN_INFO "c-jiffies = %u\n", (unsigned int) jiffies);
}
}
#endif
// issue SIGRT4 signal to the task
send_sig(SIGRT4, tasks[data].rt4_task, 1);
// restart the timer
tasks[data].rt4_timer.expires = jiffies + TIMER_CT; // 50ms
add_timer(&tasks[data].rt4_timer);
return;
}
static int rt4_open(struct inode *inode, struct file *file)
{
int i;
for( i = 0; i < MAX_TASK; i++)
{
if( tasks.pid == 0 )
{
break;
}
if( tasks.pid == current->pid )
{
// already opened
return -EBUSY;
}
}
if( i == MAX_TASK )
{
// no more slot left
return -EMFILE;
}
#if 0
if( i == 0 )
{
// initial testing count for timer 0 only.
testingct = 0;
}
#endif
// set timer function to be handled
tasks.rt4_timer.expires = jiffies + TIMER_CT;
tasks.rt4_timer.data = i; //data to be passed to the timer handler
add_timer(&tasks.rt4_timer); // start timer
// mark current processor for receiving signal.
tasks.rt4_task = current;
tasks.pid = current->pid;
// printk( KERN_INFO "SIGRT4 timer resource: %d for process pid %d \n", i, current->pid);
return 0;
}
/*
* Shut off the timer.
* Note: if we really have enabled the watchdog, there
* is no way to turn off.
*/
static int rt4_release(struct inode *inode, struct file *file)
{
int i;
for( i = 0; i < MAX_TASK; i++ )
{
if( tasks.pid == current->pid )
{
tasks.pid = 0;
del_timer_sync(&tasks.rt4_timer);
}
}
return 0;
}
// kernel interface
static struct file_operations rt4_fops = {
.owner = THIS_MODULE,
.open = rt4_open,
.release = rt4_release,
};
static struct miscdevice rt4_miscdev = {
.minor = RT4_MINOR,
.name = "irSIGRT4",
.fops = &rt4_fops,
};
// module initial
static int __init rt4_init_module( void )
{
int i;
if( misc_register(&rt4_miscdev) )
{
return -ENODEV;
}
for( i= 0; i < MAX_TASK; i++ )
{
// initial timer
init_timer(&tasks.rt4_timer);
tasks.rt4_timer.function = &rt4_timer_handler;
tasks.pid = 0;
}
printk( KERN_INFO DRIVER_NAME " $Revision: " VER "$ initializing\n");
return 0;
}
// module cleanup -- no need if use __initcall
static void __exit rt4_cleanup_module( void )
{
int i;
for( i = 0; i < MAX_TASK; i++ )
{
// stop timer
del_timer_sync(&tasks.rt4_timer);
}
misc_deregister(&rt4_miscdev);
printk( KERN_INFO "SIGRT4 generator is unloaded\n");
}
// after testing, following two lines can be commented out
// and use last line of the code __initcall(), it will be called
// in the linux initial procedure and the module will be installed
// for an embedded system.
module_init( rt4_init_module );
module_exit( rt4_cleanup_module );
MODULE_AUTHOR( "Qunyi Cao" );
MODULE_DESCRIPTION( "A module to generating SIGRT4 signal" );
MODULE_LICENSE( "GPL" ); |
|