Hello,
I'm working on a MPC8347 with Linux-2.6.23 and xenomai-2.4.0.
And I have an issue with use of rt_heap_create and alloc.
When I create the memory heap, the result is that I lost the value of my
function parameters.
Here is my code :
*Driver code : *
static void *sp_kHeapMem = NULL;
typedef struct t_ArgumentTxCreateHeap t_ArgumentTxCreateHeap;
struct t_ArgumentTxCreateHeap
{
RT_HEAP *p_Heap;
void **p_HeapMem;
char *name;
int NbyteHeap;
};
/**************************************************************/
/* dfpgatx_Ioctl=Fonction ioctl */
/**************************************************************/
static int dfpgatx_Ioctl(struct rtdm_dev_context *p_Context,
rtdm_user_info_t *p_UserInfo,
unsigned int Cmd,
void *p_Argument)
{
// p_Ctx : pointeur sur la structure t_FpgaTxContext
t_FpgaTxContext *p_Ctx = (t_FpgaTxContext *)p_Context->dev_private;
int ret = 0;
switch (Cmd)
{
case TX_CREATE_HEAP : {
// p_ArgUser : pointeur sur la structure t_ArgumentTxCreateHeap cote
utilisateur
t_ArgumentTxCreateHeap *p_ArgUser = (t_ArgumentTxCreateHeap
*)p_Argument;
// Arg : structure t_ArgumentTxCreateHeap cote noyau
t_ArgumentTxCreateHeap Arg;
RT_HEAP_INFO HeapInfo;
char *name = NULL;
// Copie de la structure t_ArgumentTxCreateHeap de l'espace
utilisateur vers l'espace noyau
if (
rtdm_copy_from_user(p_UserInfo,&Arg,p_ArgUser,sizeof(t_ArgumentTxCreateHeap))
!= 0 )
{
rtdm_printk("Echec de la copie de la structure
t_ArgumentTxCreateHeap de l'espace utilisateur vers l'espace noyau\n");
return -ECPYUSERKERN;
}
sp_kHeapMem = kmalloc(Arg.NbyteHeap, GFP_KERNEL);
name = kmalloc((strlen(Arg.name)+1), GFP_KERNEL);
// Copie du name de l'espace utilisateur vers l'espace noyau
if ( (ret = rtdm_copy_from_user(p_UserInfo, name, Arg.name, (strlen(
Arg.name)+1))))
{
rtdm_printk("Echec de la copie de p_HeapMem de l'espace
utilisateur vers l'espace noyau\n");
return -ECPYUSERKERN;
}
// Creation d'un espace memoire "memory heap" partage User/Kernel,
single Block et compatible DMA
if((ret = rt_heap_create(Arg.p_Heap, name , Arg.NbyteHeap,
H_SHARED|H_DMA )))//H_SHARED|H_DMA
{
rtdm_printk("Impossible de creer l'espace memoire Heap : ret =
%d\n", ret);
}
rt_task_set_mode(0 ,T_PRIMARY, NULL);
ret = rt_heap_alloc(Arg.p_Heap, Arg.NbyteHeap, TM_INFINITE,
&sp_kHeapMem);
rt_heap_inquire(Arg.p_Heap, &HeapInfo);
// Copie du p_HeapMem de l'espace noyau vers l'espace utilisateur
if ( rtdm_copy_to_user(p_UserInfo,Arg.p_HeapMem,&sp_kHeapMem,
Arg.NbyteHeap) != 0 )
{
rtdm_printk("Echec de la copie de p_HeapMem de l'espace noyau
vers l'espace utilisateur\n");
ret = -ECPYUSERKERN;
}
kfree(sp_kHeapMem);
break;
}
default:
rtdm_printk("Erreur : Commande non reconnue\n");
ret = -EINVAL;
break;
}
return ret;
}
/*******************************************************/
/* Structures rtdm_device */
/*******************************************************/
static struct rtdm_device t_FpgaTxDevice = {
struct_version: RTDM_DEVICE_STRUCT_VER,
device_flags: RTDM_NAMED_DEVICE,
context_size: sizeof(t_FpgaTxContext),
device_name: DEV_FILE_FPGATX,
open_rt: NULL,
open_nrt: dfpgatx_Open,
ops:{
close_rt: NULL,
close_nrt: dfpgatx_Close,
ioctl_rt: dfpgatx_Ioctl,
ioctl_nrt: dfpgatx_Ioctl,
read_rt: NULL,
read_nrt: NULL,
write_rt: NULL,
write_rt: NULL,
recvmsg_rt: NULL,
recvmsg_nrt:NULL,
sendmsg_rt: NULL,
sendmsg_nrt:NULL,
},
device_class: RTDM_CLASS_EXPERIMENTAL,
device_sub_class: 222,
driver_name: DRV_NAME,
peripheral_name: DEV_FILE_NAME,
provider_name: "-",
proc_name: t_FpgaTxDevice.device_name,
};
/****************************************/
/* Init Driver */
/****************************************/
static int dfpgatx_Init(void)
{
if(rtdm_dev_register(&t_FpgaTxDevice)!=0)
rtdm_printk("Enregistrement impossible du device FPGA TX \n");
else
rtdm_printk("Initialisation OK\n");
return 0;
}
/***************************************/
/* Exit Driver */
/***************************************/
static void dfpgatx_Exit(void)
{
if(rtdm_dev_unregister(&t_FpgaTxDevice,0))
rtdm_printk("Desabonnement KO\n");
else
rtdm_printk("Desabonnement OK\n");
}
module_init(dfpgatx_Init);
module_exit(dfpgatx_Exit);
*User code : (I launch WFPGATX_TestDMA() in a real-time task)*
typedef struct t_ArgumentTxCreateHeap t_ArgumentTxCreateHeap;
struct t_ArgumentTxCreateHeap
{
RT_HEAP *p_Heap;
void **p_HeapMem;
char *name;
int NbyteHeap;
};
static int s_DevFpgaTx = 0;
int WFPGATX_CreateHeap(RT_HEAP *p_Heap, char* name, void **const p_HeapMem,
const int NbyteHeap)
{
int ret = ETX_NOERROR;
t_ArgumentTxCreateHeap ArgCreateHeap;
RT_HEAP_INFO HeapInfo;
rt_task_set_mode(T_PRIMARY ,0, NULL);
ArgCreateHeap.p_HeapMem = p_HeapMem;
ArgCreateHeap.NbyteHeap = NbyteHeap;
ArgCreateHeap.p_Heap = p_Heap;
ArgCreateHeap.name = name;
if(rt_dev_ioctl(s_DevFpgaTx, TX_CREATE_HEAP, &ArgCreateHeap))
return -ETX_EXEC;
return ret;
}
int WFPGATX_TestDMA(void *const p_Buffer, char *p_BufferRec, const int
Nbyte)
{
int ret = ETX_NOERROR;
void *p_HeapMem = NULL;
RT_HEAP Heap;
int i = 0;
printf("Nbyte %d\n",Nbyte );
printf("BufferRec %p\n",p_BufferRec );
WFPGATX_CreateHeap(&Heap, "HeapTxTestDMA", &p_HeapMem, Nbyte);
printf("Nbyte %d\n",Nbyte );
printf("BufferRec %p\n",p_BufferRec );
printf("p_HeapMem %p\n",p_HeapMem );
return ret;
}
int WFPGATX_End()
{
int ret = ETX_NOERROR;
// On effectue la fermeture du device
rt_dev_close(s_DevFpgaTx);
return ret;
}
int WFPGATX_Init(const int TaskPrio)
{
int ret = ETX_NOERROR;
// On effectue l'ouverture du device
s_DevFpgaTx = rt_dev_open(DEV_FILE_FPGATX, 0);
if(s_DevFpgaTx < 0)
{
printf("Impossible d'ouvrir le device\n");
return -ETX_EXEC;
}
return ret;
}
*
And here is my trace : *
[ 35.061131] Unable to handle kernel paging request for data at address
0x30036f24
[ 35.068793] Faulting instruction address: 0xc0065480
[ 35.073783] Oops: Kernel access of bad area, sig: 11 [#1]
[ 35.080561] PREEMPT TH IPBB
[ 35.083365] Modules linked in: DFPGATX_Main DGPIO_PCA9698
[ 35.088797] NIP: c0065480 LR: c0065d08 CTR: c0064ebc
[ 35.093776] REGS: c06b3c30 TRAP: 0300 Not tainted (2.6.23)
[ 35.099535] MSR: 00001032 <ME,IR,DR> CR: 42004424 XER: 20000000
[ 35.105684] DAR: 30036f24, DSISR: 20000000
[ 35.109791] TASK = cfe23410[745] 'Main_TestDMA' THREAD: c06b2000
[ 35.115638] GPR00: 00000001 c06b3ce0 cfe23410 c03ce0a4 00000000 00000000
c03c0000 c0398980
[ 35.124068] GPR08: c0398980 c03e0000 c0398980 00000000 22002422 1001c37c
0fffa000 00000001
[ 35.132498] GPR16: c03d0000 c0384380 c03c9bc0 00000058 c03b0000 c03dc7d0
c03dc804 c03a0000
[ 35.140928] GPR24: cfc3d0a0 c0398980 cfc3d0d4 c03b0000 00000000 30036f24
30036de0 00000001
[ 35.149538] NIP [c0065480] __shadow_eventcb+0x5c4/0x1424
[ 35.154894] LR [c0065d08] __shadow_eventcb+0xe4c/0x1424
[ 35.160144] Call Trace:
[ 35.162595] [c06b3ce0] [c0065d08] __shadow_eventcb+0xe4c/0x1424
(unreliable)
[ 35.169688] [c06b3d20] [c0056db8] detach_ppd+0x38/0x60
[ 35.174855] [c06b3d40] [c0058ad0] cleanup_event+0xd4/0x19c
[ 35.180370] [c06b3d70] [c0049d0c] __ipipe_dispatch_event+0x9c/0x1cc
[ 35.186678] [c06b3dc0] [c001a9b8] mmput+0x6c/0x144
[ 35.191508] [c06b3dd0] [c001ed6c] exit_mm+0xac/0x110
[ 35.196505] [c06b3df0] [c0020194] do_exit+0x164/0x96c
[ 35.201584] [c06b3e30] [c00209d4] do_group_exit+0x38/0xbc
[ 35.207013] [c06b3e40] [c002cafc] get_signal_to_deliver+0x29c/0x4a0
[ 35.213327] [c06b3e80] [c0009150] do_signal+0x44/0x294
[ 35.218502] [c06b3f40] [c0010a84] do_user_signal+0x74/0xc4
[ 35.224027] --- Exception: c00 at 0xffaa228
[ 35.228228] LR = 0xffaa200
[ 35.231286] Instruction dump:
[ 35.234265] 5400103a 7d39002e 81690000 61600001 557c07fe 90090000
2f9f0000 7ffdfb78
[ 35.242082] 419e005c 807be514 3bddfebc 7f84e378 <83fd0000> 8003fffc
3863fffc 7fead278
[ 35.250083] Fixing recursive fault but reboot is needed!
Nbyte 16
BufferRec 0x100150b0
Nbyte 0
BufferRec (nil)
p_HeapMem 0xcf164030
We see that Nbyte and BufferRec are reseted. I don't see why .
Any idea ?
Thanks in advance,
Perrine Martignoni
_______________________________________________
Xenomai-help mailing list
[email protected]
https://mail.gna.org/listinfo/xenomai-help