Does netlink use 'broadcast' for passing messages? - netlink

I am following netlink example on this question and answer.
But, I don't see a sort of connection identifier in source codes. Say:
Kernel
my_nl_sock = netlink_kernel_create(&init_net, NETLINK_USERSOCK, 0,
my_nl_rcv_msg, NULL, THIS_MODULE);
User space
nls = nl_socket_alloc();
ret = nl_connect(nls, NETLINK_USERSOCK);
ret = nl_send_simple(nls, MY_MSG_TYPE, 0, msg, sizeof(msg));
where NETLINK_USERSOCK and MY_MSG_TYPE don't seem to be a connection identifier.
In such a case, how does netlink know which data comes from which user space app or kernel module and which user space app or kernel module the data should go?
In my guess, netlink receives data from user space app or kernel module and broadcasts it. And every netlink-connected app or module checks message type if data is destined to 'me'
Is what I think right?

Firstly, I recommend to read some doc, for example http://www.linuxfoundation.org/collaborate/workgroups/networking/generic_netlink_howto
To communicate you have to register a family with supported operations. It can be done with the following functions
int genl_register_family( struct genl_family *family)
int genl_register_ops( struct genl_family * family, struct genl_ops *ops)
An example of a family definition:
/*
* Attributes (variables): the index in this enum is used as a reference for the type,
* userspace application has to indicate the corresponding type
*/
enum {
CTRL_ATT_R_UNSPEC = 0,
CTRL_ATT_CNT_SESSIONS,
__CTRL_ATT_R_MAX
};
#define CTRL_ATT_R_MAX ( __CTRL_ATT_R_MAX - 1 )
#define CTRL_FAMILY "your-family"
#define CTRL_PROTO_VERSION 1
/* Family definition */
static struct genl_family ctrl_bin_gnl_family = {
.id = GENL_ID_GENERATE, // genetlink should generate an id
.hdrsize = 0,
.name = CTRL_FAMILY, // the name of this family, used by userspace application
.version = CTRL_PROTO_VERSION, // version number
.maxattr = CTRL_ATT_R_MAX, // max number of attr
};
An example of an operation definition:
struct genl_ops ctrl_info = {
.cmd = CTRL_CMD_INFO,
.flags = 0,
.policy = 0, // you can use policy if you need
.doit = 0, // set this callback if this op does some interval stuff
.dumpit = __info, // set this callback if this op dump data
};
After that you can use in your userspace app your family and operations to communicate. Make a connection:
struct nl_sock * _nl = nl_socket_alloc();
int ret = genl_connect(nl);
// test if fail
int gid = genl_ctrl_resolve( nl, CTRL_FAMILY );
// test if fail
Send info operation
struct nl_msg * msg = msg_alloc(
CTRL_CMD_INFO,
NLM_F_DUMP
);
int ret = nl_send_auto(_nl, msg );
// test if fail
// wait for the ack
// read a reply

Related

RX Fifo1 for CAN is not generating an interrupt callback (basically it is not receiving the data)

There are two types of messages on the CAN bus. Those are broadcast message and default message. Currently, I'm using fifo0 for both the message(which works perfectly fine). But I would like to use fifo1 specially for broadcast message. Below is my initializing code
uint8 BspCan_RxFilterConfig(uint32 filterId, uint32 filterMask, uint8 filterBankId, uint8 enableFlag, uint8 fifoAssignment)
{
///\todo Add method for calculating filter on the fly
CAN_FilterTypeDef canBusFilterConfig;
FunctionalState filterEnableFlag = ENABLE;
if(enableFlag == 0)
{
filterEnableFlag = DISABLE;
}
else
{
filterEnableFlag = ENABLE;
}
/*Define filter used to determine if application needs to handle message on the CAN bus or if it should
ignore it. If the selected rx FIFO is changed, the rx functions in this module must also be updated.
Using mask mode with all bits set to "don't care"*/
canBusFilterConfig.FilterBank = filterBankId; //Identification of which of the filter banks to define.
canBusFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; //Sets whether to filter out messages based on a specific id or a list
canBusFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; //Sets the width of the filter, 32-bit width means filter applies to full range of std id, extended id, IDE, and RTR bits
canBusFilterConfig.FilterIdHigh = (0xFFFF0000 & filterId)>>16; //For upper 16 bits, dominant bit is expected (logic 0)
canBusFilterConfig.FilterIdLow = 0x0000FFFF & filterId; //For Lower 16 bits, dominant bit is expected (logic 0)
canBusFilterConfig.FilterMaskIdHigh = (0xFFFF0000 & filterMask)>>16; //Upper 16 bits are don't care
canBusFilterConfig.FilterMaskIdLow = 0x0000FFFF & filterMask; //Lower 16 bits are don't care
//canBusFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0; //Sets which rx FIFO to which to apply the filter settings
canBusFilterConfig.FilterActivation = filterEnableFlag;
canBusFilterConfig.SlaveStartFilterBank = 1; //Bank for the defined filter. Arbitrary value.
if (fifoAssignment == 0)
{
canBusFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
}
else
{
canBusFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO1;
}
//Only fails if CAN peripheral is not in ready or listening state
if (HAL_CAN_ConfigFilter(&gCanBusH, &canBusFilterConfig) != HAL_OK)
{
return(ERR_CAN_INIT_FAILED);
}
else
{
return(SZW_NO_ERROR);
}
}//end BspCan_RxFilterConfig
When initializing, fifo0 works perfectly but fifo1 doesn't. If I just initialize fifo1 for both types of messages, it doesn't generate the interrupt. What am I doing wrong over here ? How to i initialize fifo1 to make it work and generate interrupt? I also tried without using digital filters still no luck.
Thanks in advance,

'proc' undefined when trying to add a system call to xv6

I'm trying to add a "clone" system call to the xv6 os. The call creates a new kernel thread which shares the calling process’s address space. The following is my code in proc.c
int clone(void(*fcn)(void*), void* arg, void* stack)
{
int i, pid;
struct proc *np;
int *myarg;
int *myret;
if((np = allocproc()) == 0)
return -1;
np->pgdir = proc->pgdir; //Here's where it tell's me proc is undefined
np->sz = proc->sz;
np->parent = proc;
*np->tf = *proc->tf;
np->stack = stack;
np->tf->eax = 0;
np->tf->eip = (int)fcn;
myret = stack + 4096 - 2 * sizeof(int *);
*myret = 0xFFFFFFFF;
myarg = stack + 4096 - sizeof(int *);
*myarg = (int)arg;
np->tf->esp = (int)stack + PGSIZE - 2 * sizeof(int *);
np->tf->ebp = np->tf->esp;
np->isthread = 1;
for(i = 0; i < NOFILE; i++)
if(proc->ofile[i])
np->ofile[i] = filedup(proc->ofile[i]);
np->cwd = idup(proc->cwd);
safestrcpy(np->name, proc->name, sizeof(proc->name));
pid = np->pid;
acquire(&ptable.lock);
np->state = RUNNABLE;
release(&ptable.lock);
return pid;
}
Most of the implementations I found look just like this, however, whenever I try to make it tells me that 'proc' is undefined. Most implementations of clone that I've seen look nearly identical, with all of them utilizing proc. I'd be happy to share my sysproc.c code as well if that would help in any way.
Thank you!
This has nothing to do with your system call's implementation because proc global variable is being set by the scheduler right before resuming a selected "runnable" process.
The reason for null would probably be because calling this function from a wrong context.
A system call implementation is expected to be executed from a wrapping function named sys_mysysfunc that syscall function called due to a system call inerrupt initiated by a user application code.
Please share with us your entire implementation flow for additional assistance.

Using f_mount to read and write data to text file

In my Application I need to open, read and write data to a text file using the calls f_open, f_read, and f_write.
It is failing to open the .txt file
res = f_open(&f_header.file, file_path, FA_OPEN_EXISTING | FA_WRITE | FA__WRITTEN | FA_READ | FA_CREATE_NEW );
printf("res value after f open %d \n\r",res);
if (res != FR_OK) {
printf("Failed to open %s, error %d\n\r", file_path, res);
}
This is giving error:
FR_NOT_ENABLED, /* (12) The volume has no work area */
For solving this error application program needs to perform f_mount function after each media change to force cleared the filesystem object.
How to use f_mount() call in this application to solve this issue?
I'm not clear about the 2nd parameter.
I added this f_mount(&fs0, "0://", 1); to solve this issue.
Before the f_open call. It is not taking f_mount() call also.
res=f_mount(&fs0,"0://", 1);
res = f_open(&f_header.file, file_path, FA_OPEN_EXISTING | FA_WRITE | FA__WRITTEN | FA_READ | FA_CREATE_NEW );
The code is stopping while run time before the f_mount()
Here is the source code for f_mount which I'm using:
FRESULT f_mount (
FATFS* fs, /* Pointer to the file system object (NULL:unmount)*/
const TCHAR* path, /* Logical drive number to be mounted/unmounted */
BYTE opt /* 0:Do not mount (delayed mount), 1:Mount immediately */
)
{
FATFS *cfs;
int vol;
FRESULT res;
const TCHAR *rp = path;
vol = get_ldnumber(&rp);
if (vol < 0) return FR_INVALID_DRIVE;
cfs = FatFs[vol]; /* Pointer to fs object */
if (cfs) {
#if _FS_LOCK
clear_lock(cfs);
#endif
#if _FS_REENTRANT /* Discard sync object of the current volume */
if (!ff_del_syncobj(cfs->sobj)) return FR_INT_ERR;
#endif
cfs->fs_type = 0; /* Clear old fs object */
}
if (fs) {
fs->fs_type = 0; /* Clear new fs object */
#if _FS_REENTRANT /* Create sync object for the new volume */
if (!ff_cre_syncobj((BYTE)vol, &fs->sobj)) return FR_INT_ERR;
#endif
}
FatFs[vol] = fs; /* Register new fs object */
if (!fs || opt != 1) return FR_OK; /* Do not mount now, it will be mounted later */
res = find_volume(&fs, &path, 0); /* Force mounted the volume */
LEAVE_FF(fs, res);
}
The code is not showing any error/warnings at the time of make file.
I'm sure there is no problem with the code.
There is nothing wrong with the code.
Is this some problem related to the memory allocation or out of memory in emmc. What are the possible reason for this behaviour.
According to http://elm-chan.org/fsw/ff/doc/mount.html:
FRESULT f_mount (
FATFS* fs, /* [IN] Filesystem object */
const TCHAR* path, /* [IN] Logical drive number */
BYTE opt /* [IN] Initialization option */
);
Parameters
fs
Pointer to the filesystem object to be registered and cleared. Null pointer unregisters the registered filesystem object.
path
Pointer to the null-terminated string that specifies the logical drive. The string without drive number means the default drive.
opt
Mounting option. 0: Do not mount now (to be mounted on the first access to the volume), 1: Force mounted the volume to check if it is ready to work.
In other words, the second parameter is how you want to refer to this particular filesystem when later working with it.
For example, mounting it like so:
f_mount(&fs0, "0://", 1);
you would then be able to open files like this:
f_open(fp, "0://path/to/file", FA_CREATE_ALWAYS);

EGL: Does a FBO get created when creating a pBuffer surface?

I am working with EGL on an ARM GPU, and I am using a pbuffer to do off screen rendering. I follow the standard procedures as described in the documentation to set everything up:
EGLDisplay display;
EGLConfig config;
EGLContext context;
EGLSurface surface;
EGLint num_config;
// assume I allocated both attrib lists somewhere
attribute_list[0] = EGL_SURFACE_TYPE;
attribute_list[1] = EGL_PBUFFER_BIT;
attribute_list[2] = EGL_RENDERABLE_TYPE;
attribute_list[3] = EGL_OPENGL_ES2_BIT;
attribute_list[4] = EGL_OPENGL_RED_SIZE;
attribute_list[5] = 8;
attribute_list[6] = EGL_OPENGL_GREEN_SIZE;
attribute_list[7] = 8;
attribute_list[8] = EGL_OPENGL_BLUE_SIZE;
attribute_list[9] = 8;
attribute_list[9] = EGL_OPENGL_ALPHA_SIZE;
attribute_list[10] = 8;
attribute_list[11] = EGL_OPENGL_DEPTH_SIZE;
attribute_list[12] = 8;
attribute_list[13] = EGL_NONE;
pbuffer_attribs[0] = EGL_WIDTH;
pbuffer_attribs[1] = 512;
pbuffer_attribs[2] = EGL_HEIGHT;
pbuffer_attribs[3] = 512;
pbuffer_attribs[4] = EGL_NONE;
/* get an EGL display connection */
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
/* initialize the EGL display connection */
eglInitialize(display, NULL, NULL);
/* get an appropriate EGL frame buffer configuration */
eglChooseConfig(display, attribute_list, &config, 1, &num_config);
/* create an EGL rendering context */
context = eglCreateContext(display, config, EGL_NO_CONTEXT, NULL);
/* create the surface */
surface = eglCreatePbufferSurface(display, config, pbuffer_attribs);
/* connect the context to the surface */
eglMakeCurrent(display, surface, surface, context);
After this, my reads and writes should be associated with this offscreen pBuffer, correct? Does this pBuffer have a FBO which is distinct from the default framebuffer associated with it? The issue I am running into is I get a GL_FRAMEBUFFER_UNDEFINED error when I try to glReadPixels. This error happens when:
GL_FRAMEBUFFER_UNDEFINED is returned if target is the default framebuffer, but the default framebuffer does not exist.
My reading of this error is I am rendering to the default FBO and not to the pBuffer FBO. Is this interpretation correct? If so, what else do I need to do so I can read and write to the pBuffer FBO?
If the above sequence completes successfully (without errors), then, yes, the offscreen pBuffer becomes the default framebuffer for the OpenGL ES context and all reads and writes will be associated with the pBuffer (unless a non-default FBO is bound).
It's worth checking that eglGetError() returns EGL_SUCCESS after each EGL call. The following part of your code listing looks suspicious:
attribute_list[9] = 8;
attribute_list[9] = EGL_OPENGL_ALPHA_SIZE;

How to define end in objective C

OSStatus SetupBuffers(BG_FileInfo *inFileInfo)
{
int numBuffersToQueue = kNumberBuffers;
UInt32 maxPacketSize;
UInt32 size = sizeof(maxPacketSize);
// we need to calculate how many packets we read at a time, and how big a buffer we need
// we base this on the size of the packets in the file and an approximate duration for each buffer
// first check to see what the max size of a packet is - if it is bigger
// than our allocation default size, that needs to become larger
OSStatus result = AudioFileGetProperty(inFileInfo->mAFID, kAudioFilePropertyPacketSizeUpperBound, &size, &maxPacketSize);
AssertNoError("Error getting packet upper bound size", end);
bool isFormatVBR = (inFileInfo->mFileFormat.mBytesPerPacket == 0 || inFileInfo- >mFileFormat.mFramesPerPacket == 0);
CalculateBytesForTime(inFileInfo->mFileFormat, maxPacketSize, 0.5/*seconds*/, &mBufferByteSize, &mNumPacketsToRead);
// if the file is smaller than the capacity of all the buffer queues, always load it at once
if ((mBufferByteSize * numBuffersToQueue) > inFileInfo->mFileDataSize)
inFileInfo->mLoadAtOnce = true;
if (inFileInfo->mLoadAtOnce)
{
UInt64 theFileNumPackets;
size = sizeof(UInt64);
result = AudioFileGetProperty(inFileInfo->mAFID, kAudioFilePropertyAudioDataPacketCount, &size, &theFileNumPackets);
AssertNoError("Error getting packet count for file", end);***>>>>this is where xcode says undefined<<<<***
mNumPacketsToRead = (UInt32)theFileNumPackets;
mBufferByteSize = inFileInfo->mFileDataSize;
numBuffersToQueue = 1;
}
//Here is the exact error
label 'end' used but not defined
I have that error twice
If you look at the SoundEngine.cpp source that the snippet comes from, you'll see it's defined on the very next line:
end:
return result;
It's a label that execution jumps to when there's an error.
Uhm, the only place I can find AssertNoError is here in Technical Note TN2113. And it has a completely different format. AssertNoError(theError, "couldn't unregister the ABL"); Where is AssertNoError defined?
User #Jeremy P mentions this document as well.