Carlos, I forgot to mention before also that you seem to have a flaw in your code some where. I mentioned clearing your data variables already, but there is potentially more there too is you're getting duplicate time stamps, and data. The first impression I get from this is that
- a) you're not clearing your data variables between reads / writes on the ARM side. And . . . - b) You have no locking mechanism between the PRU, and ARM to tell the ARM side program it is ok to read the data. This is what I was trying to get at last night, but I always feel like I'm in a hurry because I'm either coding, or reading about something new to me related to what I'm coding . . . and hence why I respond with so many darned posts . . . heh. As I have a lot on my mind . . . On Thu, Sep 10, 2015 at 9:55 PM, William Hermans <[email protected]> wrote: > *This can mean that one side or the other may stall while waiting on the >> other side to complete it's task.* > > > This is actually more of a cautionary remark than anything. If you use > such a technique "smartly", it can be very fast. As another example . . . > the code I've been working on recently involves reading in data from the > CAN peripheral, and building multi frame packets ( varying in size ) out of > this data. Then writing this data to a shared memory file. After this the > shared memory read side reads the data, and put this out over a web socket > to a web browser client. > > With this in mind, I've been able to send 280+ messages a second via a web > socket to the web browser. More realistically though, I'm able to give the > browser ~20 data samples a second using the technique I mentioned above. > That, and the data is multi packets, and each packet is only sent over the > CANBus ever 500ms for most packets. Then, I'm only currently tracking three > data packets . . .one of which does send out information every 100ms - > Which I realistically can not keep up with. Even if that data packet is > monitored by a separated thread. I've tested it . .. > > On Thu, Sep 10, 2015 at 9:35 PM, William Hermans <[email protected]> > wrote: > >> Nice and objective advice, I like it. In fact, the interrupt system works >>> great to signal new data to be exchanged by the two PRUs, there are just >>> the PRUs registers, no memory cache, everything completes in one pru >>> cycle... a predictable word. I was lured to think that the same would >>> happen to sync data between the PRU and the ARM. >>> Now I see that when I wrote "professional approach", even stating that I >>> am not a programmer, it may sounded offensive. So I ask, anyone who may >>> felt uncomfortable, please forgive me. That was not my intention. >>> >>> It is far more troubling to leave data variables uncleared once done >>>> with them, and not use memory use synchronization. As these can promote >>>> hard to nail down problems, as you're observing. >>>> >>> >>> >>> Anyway, stop worrying about professional and what you *think* is >>>> professional, and focus on the things that are actually important. >>>> >>> >>> Thank you very much. I will re-implement the code with this kind of >>> flagging... maybe it is the right time to dive into some posix threads >>> reading. >>> >> >> No no . . . what I mean by my comment was that it is more important to do >> a job right by you. Or put another way - Don't worry so much about what >> other people think about your code, but do what works for you, and simpler >> code generally works best. Perhaps you're familiar with the acronym >> K.I.S.S. ? e.g. "keep it simple stupid" . . . this is not meant as a >> denigrating remark. Actually the meaning I take from this is that there are >> usually more ways to do things ( in engineering ) and generally the >> simplest way is the best. For many reasons - But not always for the obvious >> reasons. >> >> So my comment about the POSIX shared memory . . . The code was more of a >> high level concept than code that you can actually use for your situation. >> Honestly I have no idea how you would implement an equivalent PRU side, but >> I'm sure it is possible. >> >> The beauty of the code is simplicity, and straight to the desired effect. >> No overhead, etc, and similar code could not get much faster . . . >> depending. One of the downsides however, is that it is a "blocking lock". >> Which means the program can not do anything after this check, until it can >> do it's thing with the shared data area. This can mean that one side or the >> other may stall while waiting on the other side to complete it's task. >> >> I also like the idea of using interrupts. However, there is probably lots >> of system overhead involved on the OS side - By comparison. Really though, >> I have no experience with using interrupts in / on an OS. Only bare metal. >> But the potential problem I'm seeing here - Is that I know that Linux works >> in time slices, and your Linux process will only get the CPU time the >> kernel lets it have. Which can be very non deterministic at times. I've >> experienced this first hand recently . . >> >> Also, I'm going to assume, and it is probably a very good assumption that >> interrupts in Linux will require a system call at minimum. Which can be bad >> for an executable that needs to be fast. As an example - looks at the speed >> difference between accessing a file using sysfs compared to mmap(). sysfs >> uses systems calls, where mmap() does not. Well, for reading / writing. >> Initializing either is / can be very close to the same. Anyway, my personal >> experience here is with using POSIX semaphores. Compared to my simplistic >> code, they were dog slow. POSIX semaphores use system calls . . . my code >> does not. Being very simple code, and very little of it. Also is is also >> very deterministic. It virtually guarantees that only one side of the >> shared memory transaction can take place, and it has to take place in a >> certain order. >> >> Interrupts between the two PRUs seems the way to go. Especially since it >> seems to be a single cycle operation on each side. For your Linux side >> application . . . I'm not so sure. But the only real way to find out is to >> implement two or more different ways of doing the same thing, and test it >> yourself. >> >> Anyway . . . I've probably beat this horse to death ;) >> >> >> On Thu, Sep 10, 2015 at 8:31 PM, Carlos Novaes <[email protected]> >> wrote: >> >>> Le jeudi 10 septembre 2015 11:50:32 UTC-3, William Hermans a écrit : >>>> >>>> *I think I got tour point here. I used the signal/interruption system >>>>> to sync between arm and pru, as it seens to me a more professional >>>>> approach >>>>> (I am not a programmer anyway...) than keep reading a status flag on the >>>>> shared memory. But It seems that the pru functions to write to the shared >>>>> ram region are not blocking and will return even if the data was not >>>>> actually written into RAM.* >>>> >>>> >>>> Do whatever makes you happy as far as fixing your problem. But know >>>> that "professionalism" has nothing to do with programming. There are ways >>>> to do somethings, and ways not to. >>>> >>> Nice and objective advice, I like it. In fact, the interrupt system >>> works great to signal new data to be exchanged by the two PRUs, there are >>> just the PRUs registers, no memory cache, everything completes in one pru >>> cycle... a predictable word. I was lured to think that the same would >>> happen to sync data between the PRU and the ARM. >>> Now I see that when I wrote "professional approach", even stating that I >>> am not a programmer, it may sounded offensive. So I ask, anyone who may >>> felt uncomfortable, please forgive me. That was not my intention. >>> >>>> >>>> It is far more troubling to leave data variables uncleared once done >>>> with them, and not use memory use synchronization. As these can promote >>>> hard to nail down problems, as you're observing. >>>> >>>> Anyway, stop worrying about professional and what you *think* is >>>> professional, and focus on the things that are actually important. >>>> >>> Thank you very much. I will re-implement the code with this kind of >>> flagging... maybe it is the right time to dive into some posix threads >>> reading. >>> >>>> >>>> >>>> On Thu, Sep 10, 2015 at 6:20 AM, Charles Steinkuehler < >>>> [email protected]> wrote: >>>> >>>>> On 9/10/2015 7:07 AM, Carlos Novaes wrote: >>>>> > I think I got tour point here. I used the signal/interruption >>>>> > system to sync between arm and pru, as it seens to me a more >>>>> > professional approach (I am not a programmer anyway...) than keep >>>>> > reading a status flag on the shared memory. But It seems that the >>>>> > pru functions to write to the shared ram region are not blocking >>>>> > and will return even if the data was not actually written into RAM. >>>>> >>>>> Writes will always complete, but it's possible to see updates happen >>>>> out of order due to hardware or compiler optimizations (that's what >>>>> memory fences are for). >>>>> >>>>> You also don't mention if "shared ram" is the PRU shared memory region >>>>> or a chunk carved out of SDRAM. The data will always be written, but >>>>> visibility rules (especially on the ARM side) will depend on the >>>>> specific code you write, the memory region flags (cache-able, I/O >>>>> region, etc), any memory barriers used, etc. >>>>> >>>>> You'll have a much easier time using the PRU shared memory region if >>>>> you're not already. >>>>> >>>>> > I will try to set some flag so signal that a chunck of data was >>>>> > already processed and will see how it performs. Another thing to >>>>> > note is that each time new data is read by ARM, another chunck of >>>>> > data is written to the same shared memory, just in a different >>>>> > location. This could cause the bus to saturate at some conditions? >>>>> >>>>> The description of your code so far hasn't sounded much like a >>>>> standard ring buffer. Writing lockless multi-threaded code is >>>>> non-trivial, and there are lots of ways to mess things up. I suggest >>>>> you either use a proper ring buffer (if you don't want dropped >>>>> samples), or a proper req/ack mechanism if you're just trying to get a >>>>> single value at a time across the PRU<>ARM boundary. >>>>> >>>>> If you want more specific help, post a link to some code for review. >>>>> >>>>> -- >>>>> Charles Steinkuehler >>>>> [email protected] >>>>> >>>>> -- >>>>> 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 [email protected]. >>>>> 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 [email protected]. >>> 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 [email protected]. For more options, visit https://groups.google.com/d/optout.
