On Mon, 24 Aug 2015 18:19:14 -0700, you wrote:

>>
>> *I know the feeling.*
>>
>> * Good luck and don't hesitate to ask for more help, or at least advice,*
>> * for whatever I can do.  Linux I can't really talk about, the*
>> * fundamentals I think I can.*
>>
>
>I think Linux in this context was not so important. I mean it is / was, but
>I generally do ok with high level on topic discussions. So long as I know
>what my options are, everything is good.

It's more of a general operating system issue, and that is fundamental
knowledge.  Personally, I don't see a problem, but the list moderators
haven't seemed to have a problem either, so that's ok.

>
>*Ask either on the list or private email if you want.*
>>
>
>I don't mind asking here if that is fine with everyone. Technically, I felt
>a little funny posting here, as it was semi off topic( in relation to the
>beaglebone ), but maybe the discussion helps someone else too ? If there is
>a problem, then I have no issues moving to another forum.

True, except it *is* to get the beaglebone working, and *is* an issue
that can bite people writing somewhat more complicated projects.

I'd hope that it will help others, and for that matter, if someone
disagrees with what I've said, I'd welcome the discussion.  

Hopefully, the concepts will help with the more complicated projects
using any sort of beagle....

Harvey

>
>On Mon, Aug 24, 2015 at 6:00 PM, Harvey White <ma...@dragonworks.info>
>wrote:
>
>> On Mon, 24 Aug 2015 17:40:33 -0700, you wrote:
>>
>> >Hey Harvey, and Walter
>> >
>> >Just kind of an update. Last night after our discussion I found a really
>> >good resource / discussion of what fork() is and the different ways it can
>> >be used. So with this information in mind along with our discussion
>> >yesterday it seems that what I want to do can indeed be done without using
>> >POSIX shared memory( I had little doubt ) - *and* seemingly more simple.
>>
>> That sounds good
>> >
>> >I'd still have to use a Semaphore - I think to keep the web server
>> callback
>> >from stalling my canbus routines. But I think that seems fairly
>> reasonable.
>> >
>>
>> That also sounds quite reasonable to do.  As your programs get more
>> complicated, you'll have to figure out how to interlock/protect/manage
>> resources.
>>
>> I have a project that manages a graphics engine (software), I2C slave
>> (ditto), heartbeat/errortask, I2C error reporting task, and the like;
>> and uses a FIFO, semaphores, queues and the like to protect resources
>> and manage memory.
>>
>> Probably a bit too complex, but it kinda grew that way.
>>
>>
>> >Still I may just implement semaphores into my current code to check it
>> out,
>> >but not sure when. Been a semi rough day, and I'm whooped . . .
>>
>> I know the feeling.
>>
>> Good luck and don't hesitate to ask for more help, or at least advice,
>> for whatever I can do.  Linux I can't really talk about, the
>> fundamentals I think I can.
>>
>> Ask either on the list or private email if you want.
>>
>> Harvey
>>
>> >
>> >On Sun, Aug 23, 2015 at 9:44 PM, William Hermans <yyrk...@gmail.com>
>> wrote:
>> >
>> >> OK have a good one, thanks for the discussion.
>> >>
>> >> On Sun, Aug 23, 2015 at 9:11 PM, Harvey White <ma...@dragonworks.info>
>> >> wrote:
>> >>
>> >>> On Sun, 23 Aug 2015 20:18:26 -0700 (PDT), you wrote:
>> >>>
>> >>> >
>> >>> >>
>> >>> >> *Well, you're certainly right that the callback is messing*
>> >>> >> * things up.  If I assume the same callback, then the callback is*
>> >>> >> * certainly changing data.  If you can set the right breakpoint, you
>> >>> can*
>> >>> >> * tag the situation *if* the breakpoint also knows that the process
>> is*
>> >>> >> * reading from the CAN bus.*
>> >>> >>
>> >>> >> * Had you considered disabling that callback function until the
>> read*
>> >>> >> * from the CANbus is finished?  Would it be practical?  That's where
>> >>> the*
>> >>> >> * semaphore might help a lot.*
>> >>> >>
>> >>> >> * what variables could be common between the two routines?*
>> >>> >>
>> >>> >> * Harvey*
>> >>> >>
>> >>> >
>> >>> >Well this is where previous experience fails me. I've pretty much
>> avoided
>> >>> >code related to threading in software. In the past. I do know of
>> fork()
>> >>> and
>> >>> >roughly what it is capable of, and I know about threads, but not to
>> >>> >implement them in C on Linux. Or what can be done with them. Lets talk
>> >>> code
>> >>> >a minute.
>> >>>
>> >>> OK, as well as I can follow it.
>> >>>
>> >>> >
>> >>> >*IPC - Server - Reads from canbus*
>> >>> >int main(){
>> >>> >    struct can_frame frame;
>> >>> >    int sock = InitializeCAN("vcan0");
>> >>> >
>> >>> >    statistics_t *stats = NULL;
>> >>> >
>> >>> >    const long shm_size = sysconf(_SC_PAGESIZE);
>> >>> >
>> >>> >    int shm_fd = shm_open("acme", O_CREAT | O_RDWR, FILE_PERMS);
>> >>>
>> >>> **NOTE:  the problem may be "acme", since we know that acme products
>> >>> are not effective against roadrunners.....
>> >>>
>> >>> >    if(shm_fd == -1)
>> >>> >        HandleError(strerror(errno));
>> >>> >
>> >>> >    const int retval = ftruncate(shm_fd, shm_size);
>> >>> >    if(retval == -1)
>> >>> >        HandleError(strerror(errno));
>> >>> >
>> >>> >    shared_memory = InitializeShm(shm_size * sizeof(char), shm_fd);
>> >>> >    close(shm_fd);
>> >>> >
>> >>> >    while(1){
>> >>> >        frame = ReadFrame(sock);
>> >>> >        if(frame.can_dlc == FRAME_DLC)
>> >>> >            stats = ProcessFastpacket(frame);
>> >>>
>> >>> right at this point, you have no protection against access and no
>> >>> interlocking.
>> >>>
>> >>> I'll have to give you pseudocode, because I don't know how to do this
>> >>> in Linux.
>> >>>
>> >>>         In the init routine, before you set up either main as a
>> >>> process (I assume you do this).  Declare a semaphore:
>> >>>
>> >>> semaphore_handle shared_access;                 // create semaphore
>> >>> handle accessible to both processes.
>> >>> semaphore_create (shared_access);                       // create
>> >>> semaphore
>> >>>
>> >>>
>> >>> then modify this next section to:
>> >>>
>> >>>         if(stats != NULL){
>> >>>         if (semaphore_take(shared_access), <wait forever>)
>> >>>         {
>> >>>                         WriteToShm(shared_memory, stats);
>> >>>                 semaphore_give (shared_access);
>> >>>         }
>> >>>         stats = NULL;
>> >>>             printf("%s", ReadFromShm(shared_memory));
>> >>>         }
>> >>>        task_delay(n);
>> >>>
>> >>> NOTE:   Process A hangs until it can "get" the semaphore; if Process B
>> >>> has it, B can keep it only long enough to send the packet
>> >>> >
>> >>> >        if(stats != NULL){
>> >>> >            WriteToShm(shared_memory, stats);
>> >>> >            stats = NULL;
>> >>> >            printf("%s", ReadFromShm(shared_memory));
>> >>> >        }
>> >>> >    }
>> >>> >}/* main() */
>> >>> >
>> >>> >
>> >>> >
>> >>> >*IPC - Client / webserver*
>> >>> >
>> >>> >int main(void) {
>> >>> >        struct mg_server *server = mg_create_server(NULL, ev_handler);
>> >>> >
>> >>> >        mg_set_option(server, "listening_port", "8000");
>> >>> >        mg_set_option(server, "document_root", "./web");
>> >>> >
>> >>> >        printf("Started on port %s\n", mg_get_option(server,
>> >>> >"listening_port"));
>> >>> >
>> >>> >        // POSIX IPC - shared memory
>> >>> >        const long shm_size = sysconf(_SC_PAGESIZE);
>> >>> >        int shm_fd = shm_open("file", O_CREAT | O_RDWR, FILE_PERMS);
>> >>> >        if(shm_fd == -1)
>> >>> >                HandleError(strerror(errno));
>> >>> >
>> >>> >        const int retval = ftruncate(shm_fd, shm_size);
>> >>> >        if(retval == -1)
>> >>> >                HandleError(strerror(errno));
>> >>> >
>> >>> >        shared_memory = InitializeShm(shm_size * sizeof(char),
>> shm_fd);
>> >>> >
>> >>> >        close(shm_fd);
>> >>> >
>> >>> >        char id = 0x00;
>> >>> >        for (;;) {
>> >>> >                mg_poll_server(server, 10);
>> >>> >
>> >>> then do the same here
>> >>>
>> >>>         if (semaphore_take(shared_access), <wait forever>)
>> >>>         {
>> >>>                         if(shared_memory->sdata.data[19] != id){
>> >>>  push_message(server,shared_memory->sdata.data);
>> >>>                                         id =
>> >>> shared_memory->sdata.data[19];
>> >>>                         }
>> >>>                 semaphore_give (shared_access);
>> >>>         }
>> >>>         task_delay (n clock ticks);
>> >>>
>> >>> semaphore_take gets the semaphore if and only if it's available.  It
>> >>> does so in a thread safe manner.  the <wait_forever> is whatever value
>> >>> the system uses to tell the process to hang.  You don't want the
>> >>> process to wait and then just go.
>> >>>
>> >>> Because each example here releases the semaphore (semaphore_give) if
>> >>> and only if it could get it, and since giving and taking the semaphore
>> >>> is thread safe, the two threads should be fine.
>> >>>
>> >>> So your "consumer" thread can't check for valid data until there's
>> >>> something there.   When it first starts up, it has to get bad (null)
>> >>> data and throw that away, since you can't guarantee that one thread
>> >>> starts before the other (unless you block the thread using a suspend,
>> >>> but that's not really the best thing to do), so you have to consider
>> >>> that you have two parallel and independent threads.
>> >>>
>> >>> The consumer thread can access shared memory only when it's not been
>> >>> actively written to.  It has to figure out if data is good and what to
>> >>> do with it.  However, once written, that data will remain uncorrupted
>> >>> until the consumer has read and processed it (because the consumer has
>> >>> the semaphore and doesn't give it up until then).
>> >>>
>> >>> The producer thread checks to see if the data is there to send,
>> >>> accesses shared memory by getting the semaphore (when the consumer is
>> >>> not reading it), and then writes that shared memory.  It then releases
>> >>> the semaphore, goes idle (because the task switcher has to have a time
>> >>> to start up the other task unless you have multiple cores), and then
>> >>> checks for data, and waits to see when it can write that data.
>> >>>
>> >>> The typical task clock is either 1 ms or 10 ms, and the clock tick is
>> >>> that (1 ms or 10 ms per tick).  You play with the values for best
>> >>> throughput on the n delays.
>> >>>
>> >>>
>> >>> >                if(shared_memory->sdata.data[19] != id){
>> >>> >                        push_message(server,
>> shared_memory->sdata.data);
>> >>> >                        id = shared_memory->sdata.data[19];
>> >>> >                }
>> >>> >        }
>> >>> >
>> >>> >        mg_destroy_server(&server);
>> >>> >        return 0;
>> >>> >}
>> >>> >
>> >>> >In the context of whats interesting where threading is concerned. The
>> >>> loops
>> >>> >in each executable here might be useful. If somehow each, or even just
>> >>> the
>> >>> >for loop in the IPC client could somehow use objects in memory from
>> the
>> >>> IPC
>> >>> >server.
>> >>>
>> >>> That was the shared memory, right?
>> >>>
>> >>> >That is let us suppose for a minute IPC was removed entirely, then
>> >>> >somehow I could turn off the callback in the IPC client. This is what
>> I'm
>> >>> >having a problem imagining. How could this be done ?
>> >>>
>> >>> You may possibly be able to schedule *when* the callback happens.
>> >>>
>> >>> What causes the callback, sending a CAN message?
>> >>>
>> >>> > In the context of
>> >>> >libmongoose I'm not sure. In the context of threading or using fork()
>> I'm
>> >>> >also not sure.
>> >>>
>> >>> Fork creates a separate process which can be controlled or killed as
>> >>> needed, running as a sub-process (IIRC).
>> >>>
>> >>> you're dealing with creating two processes (really two programs) and
>> >>> interprocess communication.
>> >>>
>> >>> >But if I could somehow through using threading context to
>> >>> >disable the callback I think that would be ideal. That way I could
>> simply
>> >>> >disable that whole thread for a fraction of a second, and then resume
>> it
>> >>> >once a fastpacket is constructed.
>> >>>
>> >>>
>> >>>
>> >>> Well, synchronizing the two tasks with semaphores says that if the
>> >>> callback happens and you can turn off that callback, then the data is
>> >>> ok as long as you can schedule the callback.  No idea when that
>> >>> happens.
>> >>>
>> >>> So you maybe able to
>> >>> 1) produce data
>> >>> 2) keep from overwriting it
>> >>> 3) enable the consumer to read data
>> >>> 4) have it send data (and I assume the callback happens here)
>> >>> 5) data is clobbered in the shared area, but we don't care since it's
>> >>> sent already
>> >>> 6) give the semaphore back allowing new data to be written
>> >>> 7) that data can't be clobbered by the callback (assuming) until after
>> >>> it's read and in the send process
>> >>>
>> >>> May solve the problem...
>> >>>
>> >>>
>> >>> >
>> >>> >Anyway, a little information that might be needed. socketCAN reads
>> data
>> >>> in
>> >>> >8 byte lengths for each frame..fastpackets are several frames in
>> length,
>> >>> >and with the only current one I'm tracking being 11 frames long. Or 88
>> >>> >total bytes, not discounting the initial char from each frame which
>> is a
>> >>> >sequence number. If there is a way, and I'm sure there is, I am all
>> for
>> >>> >changing from an IPC model to a threaded model. But I still have some
>> >>> >doubts. Such as will it be fast enough to track multiple fastpackets a
>> >>> >second ? Past that how complex will it be ?
>> >>>
>> >>> Won't be all that complex, I think
>> >>> the processes are written as two parts
>> >>> one is a system call to set up a process
>> >>> the other is the process itself which looks like
>> >>>
>> >>> void processA(void* arguments if any)
>> >>> {
>> >>>         //      declarations and inits the first time through
>> >>>         while (1)
>> >>>         {
>> >>>                 basic process loop;
>> >>>         }
>> >>> }
>> >>>
>> >>> not complicated at all, how to create the process ought to be well
>> >>> documented
>> >>>
>> >>> you just need to make sure that the two processes have access to
>> >>> shared memory
>> >>>
>> >>> assuming 1000 us available per process, a context switching time of 50
>> >>> us (may be shorter, but it's a number)
>> >>>
>> >>> You have 950 us to send a complete message without it having a delay
>> >>> you have that same 950 us to detect and build a message.
>> >>>
>> >>> that gives you 500 message cycles/second
>> >>>
>> >>> taking twice as long gives you 250 message cycles/second and about
>> >>> 1950 us to compose and send a message, that's with a 2 ms clock tick.
>> >>> All that clock tick does is control task switching.  The processor
>> >>> clock controls the speed of operations otherwise.
>> >>>
>> >>> >
>> >>> >I have given multiple approaches consideration, just having a hard
>> time
>> >>> >imaging how to work this out using a threading model.
>> >>>
>> >>> perhaps this might help
>> >>>
>> >>> Harvey
>> >>>
>> >>> (off to bed, have to be in training for 8 am classes in a week).
>> >>>
>> >>> --
>> >>> For more options, visit http://beagleboard.org/discuss
>> >>> ---
>> >>> You received this message because you are subscribed to the Google
>> Groups
>> >>> "BeagleBoard" group.
>> >>> To unsubscribe from this group and stop receiving emails from it, send
>> an
>> >>> email to beagleboard+unsubscr...@googlegroups.com.
>> >>> For more options, visit https://groups.google.com/d/optout.
>> >>>
>> >>
>> >>
>>
>> --
>> For more options, visit http://beagleboard.org/discuss
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "BeagleBoard" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to beagleboard+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>

-- 
For more options, visit http://beagleboard.org/discuss
--- 
You received this message because you are subscribed to the Google Groups 
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to beagleboard+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to