BeagleScope - project reports

403 views
Skip to first unread message

Zubeen Tolani

unread,
May 25, 2016, 10:59:43 AM5/25/16
to BeagleBoard GSoC
Hello Everyone,

So the coding period has already begun on 23rd May UTC and though my exams aren't completely done yet, I have started with the software things. According to the submitted proposal, my first week's goal was to get started with the ADC EVM and interfacing it using an Arduino initially. But since the hardware hasn't arrived yet. I have started with the software part of the project.

For this week first week, ie, from 23rd till 30th,

My goals will be :
1. Get started with Beagle-Logic on the latest kernel
2. Get the kernel source for the kernel-image version I am using 
3. Decide how to connect to the clock and other interfacing between PRU and ADC
4. Starting with the remoteproc drivers on the kernel-image I am using
and
5. Setting up the travis.yml script for continuous integration.

As the testing part:

1. I will do some very basic testing with beagle-logic, probably hooking up the SPI pins of arduino or BBB itself to the beagle-logic.
2. Once the source is compiled, I will pick up some lkm, from the cross-compiled source ( on my laptop ) and put them onto the BBB and try loading them.
3. If the remoteproc modules, work, I will try a GPO toggler using it.
4. For the testing part of travis, I will be making a very simple lkm, and then look at the log report by travis.

As of now:

1. I have downloaded the latest iot kernel image from http://elinux.org/Beagleboard:BeagleBoneBlack_Debian#Jessie_Snapshot_iot, as was instructed by Jason on the GSoC group https://groups.google.com/forum/#!topic/beagleboard-gsoc/lns9QnPQKnk .
The kernel version in the image came out to be 4.4.8-ti-r22.

2. I have had discussion with zmatt on #beagle and with other mentors too, on the problems that can come along with the clocking of the ADC EVM using PRU. I am working on it too .

3. I further started a search for the 4.4.8-ti-r22 kernel source. It was both a confusing and a simple task at the same time. Most of the time, I was downloading a kernel source ( clone process restarts even after a minute Internet disconnect ). So now I have linux-torvalds  and linux-stable repo on my local system. Finally with the help of Michale and Stephanie, I got the 4.4.8-ti-r22 source compiled just today morning. During all this, I realized that I was not very much active in doing my part of research, ie, I should have gone through all github repos at Robert-C-Nelson@github and their readme, but I was relying on instructions from the mentors. I am sorry for that, and that will not be repeated, for sure.

Kernel Compilation result :
 DTC     arch/arm/boot/dts/dra72-evm-lcd-osd.dtb
  DTC     arch/arm/boot/dts/dra72-evm-revc.dtb
-----------------------------
‘arch/arm/boot/zImage’ -> ‘/home/zeekhuge/Projects/OpenSource/yakbuild/deploy/4.4.8-ti-r22.zImage’
‘.config’ -> ‘/home/zeekhuge/Projects/OpenSource/yakbuild/deploy/config-4.4.8-ti-r22’
-rwxrwxr-x 1 zeekhuge zeekhuge 7.5M May 25 02:34 /home/zeekhuge/Projects/OpenSource/yakbuild/deploy/4.4.8-ti-r22.zImage
-----------------------------
Building modules archive...
Compressing 4.4.8-ti-r22-modules.tar.gz...
-rw-rw-r-- 1 zeekhuge zeekhuge 58M May 25 02:34 /home/zeekhuge/Projects/OpenSource/yakbuild/deploy/4.4.8-ti-r22-modules.tar.gz
-----------------------------
Building firmware archive...
Compressing 4.4.8-ti-r22-firmware.tar.gz...
-rw-rw-r-- 1 zeekhuge zeekhuge 1.2M May 25 02:34 /home/zeekhuge/Projects/OpenSource/yakbuild/deploy/4.4.8-ti-r22-firmware.tar.gz
-----------------------------
Building dtbs archive...
Compressing 4.4.8-ti-r22-dtbs.tar.gz...
-rw-rw-r-- 1 zeekhuge zeekhuge 909K May 25 02:34 /home/zeekhuge/Projects/OpenSource/yakbuild/deploy/4.4.8-ti-r22-dtbs.tar.gz
-----------------------------
Script Complete
eewiki.net: [user@localhost:~$ export kernel_version=4.4.8-ti-r22]
-----------------------------
zeekhuge@zeekhuge:~/Projects/OpenSource/yakbuild$ 


Okay so this current-status report.

Thank you

Zubeen Tolani

unread,
May 31, 2016, 10:02:28 PM5/31/16
to BeagleBoard GSoC
REPORT - WEEK 2

Hello Everyone,

As per the last report, I had to do some tasks by this time. No all of them have been completed successfully by now, but I have progressed in most of them.

Last week :

1. Kernel Version and Kernel Source code and remoteproc drivers:

So, It was really a pain to find the exact kernel source that are being used to build the distribution kernel images, but i am now able to reproduce the exact source code (yakbuild repo at Robert's github being the key).
I have been using kernel version 4.4.9-ti-r22, and as per Jason's instructions all the kernel images needed to be picked up from http://elinux.org/Beagleboard:BeagleBoneBlack_Debian#Jessie_Snapshot_iot, and the latest one is  4.4.9-ti-r22, which do not has PRU remoteproc driver being distributed with it. I tried to dig in and find that its the 4.4.11 release that will have PRU remoteproc drivers in it. So I downloaded the 4.4.-11-ti-r28 source and tried to port the remoteproc drivers from 4.4.11 to 4.4.8-ti-r22, but wasnt able to do this. The was of-course with the versioning_symbol. The header file include/linux/remoteproc.h in the 2 releases is different, which results in the change in the versioning_symbol.

diff linux-bb-4.4.11-ti-r28/include/linux/remoteproc.h linux-bb-4.4.8-ti-r22/include/linux/remoteproc.h
104,107d103
<  * @RSC_INTMEM:     (deprecated) dummy place-holder to provide near-term
<  *            backward compatibility.
<  * @RSC_CUSTOM:     a custom resource type that needs to be handled outside
<  *            remoteproc core.
123,125c119
<     RSC_INTMEM    = 4,
<     RSC_CUSTOM    = 5,
<     RSC_LAST    = 6,
---
>     RSC_LAST    = 4,
316,327d309
<  * struct fw_rsc_custom - custom resource definition
<  * @sub_type: implementation specific type
<  * @size: size of the custom resource
<  * @data: label for the start of the resource
<  */
< struct fw_rsc_custom {
<     u32  sub_type;
<     u32  size;
<     u8   data[0];
< } __packed;
<
< /
**
366d347
<  * @handle_custom_rsc:    hook to handle device specific resource table entries
373,374d353
<     int (*handle_custom_rsc)(struct rproc *rproc,
<                  struct fw_rsc_custom *rsc);



I tried replacing the newer remoteproc file as remoteproc_pruss and accordingly put changes in the driver's code, but that didnt work. So I will be using 4.4.11, but its not being distributed yet, so I will be building it myself and boot the BBB from it.


2. Clock Source:
The Clock source to the ADC EVM is indeed important, but since GSoC is a software project, the clock thing will be given lesser priority. The clock source will be PRU and I will be using a simple NPN transistor in common emitter mode so as to isolate the noise. If that doesn't work, I will try Michael's hack, that is, connecting the PRU GPO directly to the input source removing all the components like resistors and caps in at the clock input pin. Further, if that doesn't work either, I will just switch to lower frequencies and will try to get at higher frequencies if the time permits.

3. travis.yml
By now, I have set up the .yml file, but there is some bug in it, which I think must be very simple and will hopefully resolve it before the meeting.

4. BeagleLogic
I have just started with the Beagle-Logic and tried to built it on the 4.4.8 kernel but it got into some error. This will probably take some time.


Next Week:

The project is not going with the pace I expected. This is mostly because I didn't consider getting into issues with already present softwares. For example, I expected beaglelogic to build-able right away. Anyhow, This week I will be working out my complete time-line for the project. Along with this, I will be having following tasks to do :

1. Install the 4.4.11 kernels onto BBB or use it if its available as distribution.
2. Expecting that 4.4.11 works, I will be starting with remoteproc onto it, and get a blinky.
3. After I have a PRU blinky I will try using the various suggested methods for the clock.
4. Getting BeagleLogic working
5. A skeleton driver to communicate with the remoteproc driver.


Thank you

Robert Nelson

unread,
Jun 1, 2016, 1:54:25 AM6/1/16
to beaglebo...@googlegroups.com


On May 31, 2016 9:02 PM, "Zubeen Tolani" <me.zu...@gmail.com> wrote:
>
> REPORT - WEEK 2
>
> Hello Everyone,
>
> As per the last report, I had to do some tasks by this time. No all of them have been completed successfully by now, but I have progressed in most of them.
>
> Last week :
>
> 1. Kernel Version and Kernel Source code and remoteproc drivers:
>
> So, It was really a pain to find the exact kernel source that are being used to build the distribution kernel images, but i am now able to reproduce the exact source code (yakbuild repo at Robert's github being the key).
> I have been using kernel version 4.4.9-ti-r22, and as per Jason's instructions all the kernel images needed to be picked up from http://elinux.org/Beagleboard:BeagleBoneBlack_Debian#Jessie_Snapshot_iot, and the latest one is  4.4.9-ti-r22, which do not has PRU remoteproc driver being distributed with it. I tried to dig in and find that its the 4.4.11 release that will have PRU remoteproc drivers in it. So I downloaded the 4.4.-11-ti-r28 source and tried to port the remoteproc drivers from 4.4.11 to 4.4.8-ti-r22, but wasnt able to do this. The was of-course with the versioning_symbol. The header file include/linux/remoteproc.h in the 2 releases is different, which results in the change in the versioning_symbol.

You can just apt get update the kernel, they'll be more remoteproc stuff coming from ti.com

Otherwise here is A fresh iot image for you..

https://rcn-ee.net/rootfs/bb.org/testing/2016-05-31/iot/

With 4.4.11-ti-r29...

Btw, a few more remoteproc patches where merged today..

http://git.ti.com/gitweb/?p=ti-linux-kernel/ti-linux-kernel.git;a=shortlog;h=refs/heads/ti-rt-linux-4.4.y

They'll be part of r30 pushed out Thursday-ish..

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

Zubeen Tolani

unread,
Jun 8, 2016, 3:04:24 AM6/8/16
to BeagleBoard GSoC
REPORT - WEEK 3

Hello Everyone,

Tasks for last week were related to
-> getting BeagleLogic up
-> getting rempteproc drivers and PRUs up
-> work on the over all time line of the project
-> get the suggested clock hacks tested
-> a skeleton lkm to communicate to the remoteproc drivers.

But unfortunately, I got stomach infection and body weakness (I was already feeling unwell during the last meeting but thought that it will get okay), as a result I wasn't able to complete everything out of this task list. I am perfectly fine now and doing really hard work, to get the project in pace.

Last week :

1. Getting BeagleLogic up

After discussing it with Abhishek, I realized the remoteproc driver in kernel at the time of beaglelogic used the downcalls/upcalls approach. Which is no longer supported in the current drivers. The down/up calls essentially were like calling a specific function in the firmware and the driver module. It was implemented using the interrupts.
In the current drivers, rpmsg framework is used. It too does something similar like generation of system events in form of interrupts, but is implemented very differently and is based on a standard interface defined by rpmsg framework. So we can still use the same concept ie data Input through PRU1 and cummunication through PRU0.

2. Getting remoteproc drivers and PRUs up :

The 4.4.11-ti-r29 kernel image is working almost fine with the pru remoteproc drivers. I have been playing a bit around with the remoteproc drivers and pru code, and have made some examples : https://github.com/ZeekHuge/BeagleScope/tree/master/examples
While playing around, I found that there are still some errors and glitches there in the drivers, they are sometimes causing I/O error and non of the commands is getting . I am not sure of what is causing this error and I am not able to reproduce it on will.

Another error that i found is :

[  19.628388] virtio_rpmsg_bus virtio1: rpmsg host is online
[   19.628440] virtio_rpmsg_bus virtio1: creating channel rpmsg-pru addr 0x1f
[   19.666121] rpmsg_pru rpmsg0: new rpmsg_pru device: /dev/rpmsg_pru30
[   19.666929] rpmsg_pru rpmsg1: new rpmsg_pru device: /dev/rpmsg_pru31
[   69.758596] rpmsg_pru rpmsg0: Message length table is full
[   69.773082] rpmsg_pru rpmsg0: Message length table is full
[   69.789052] rpmsg_pru rpmsg0: Message length table is full
[   69.801003] rpmsg_pru rpmsg0: Message length table is full
[   69.816916] rpmsg_pru rpmsg0: Message length table is full
[   69.829907] rpmsg_pru rpmsg0: Message length table is full
[   69.844918] rpmsg_pru rpmsg0: Message length table is full
[   69.860527] rpmsg_pru rpmsg0: Message length table is full
[   69.876931] rpmsg_pru rpmsg0: Message length table is full
[   69.887789] rpmsg_pru rpmsg0: Message length table is full

Its probably when I am sending too many messages, not sure . Will have to dig in.



3. overall time line of the project, clock hacks
As stated above, because of being ill I was in a loss of 3-4 days in the week and when I recovered I started working on remoteproc drivers. So wasnt able to plan the overall timeline or the clock hacks.

4. skeleton driver to communicate to the PRUs
I have been reading about device drivers, remoteproc device drivers and rpmsg framework. Also I have made some note on the current remoteproc drivers. I will push them up to the repository after some cleaning work. Summarizing what I have learnd about them so far :

The pru_rproc driver handles almost everything of the pru cores . It Initializes the cores and the virtio buffers . This is done automatically when an driver sees that there is virtio devices in the resource table of the firmware. There is then some initialization of the Interrupts and associated system events. I also saw that the OCP port is being open for the PRUs that suggest that internally its the PRUs that goes and writes to the virtio buffer. Then there are some APIs pruss_get(), pruss_put(), pruss_rproc_get(), pruss_rproc_put(). These APIs provide handle to the various devices that the name says. I believe that these handles can be used by a kernel module to get the mailbox handle and the device handle. Further, the MPU need to send message to the PRU atlease once, and only then is that the PRU would get the destination address of the buffers to write into.   

Also, the PRUs can be configured using the configuration registers. There are predefined data structures for all the registers in the pru software support package which are then mapped to there actual location using the .cmd linker file. Like to get the 16-bit capture mode, we will have to do this by setting PRU0_GPI_MODE bits ( 2 bits ) in the GPCFG0 register equal to 2. This can be done with the instruction "CT_CFG.GPCFG0_bit.PRU0_GPI_MODE = 2 "


Next Week:

Tasks for the next week:
1. An lkm to communicate to the remoteproc drivers.
2. Testing clock hacks
3. Developing firmware for the two PRUs to communicate with each other and acquire input data ( PRU1 ) and communicate it to MPU ( PRU0 ).
4. Overall project timeline


Thank you

Zubeen Tolani

unread,
Jun 15, 2016, 2:32:22 AM6/15/16
to BeagleBoard GSoC
REPORT - WEEK 4

Hello Everyone,

The last week was pretty interesting. I was able to make first kernel module of the project.

Tasks for last week were:
1. An lkm to communicate to the PRUs.
2. Testing clock hacks
3. Developing firmware for the two PRUs to communicate with each other and acquire input data ( PRU1 ) and communicate it to MPU ( PRU0 ).


Last week :

1. lkm to communicate to the PRUs

So, I was able to make an example driver that would expose a char device to have somewhat control on PRUs. Since this module is an example, I have put it here in the examples folder https://github.com/ZeekHuge/BeagleScope/tree/master/examples/kernel_examples/n-blinky.

So the lkm basically uses the symbols exported by platform specific implementation of rpmsg framework drivers.

Also, I I noticed that TI has recently changed the implementation of RPMSG for the board. So, now the most recent RPMSg uses interrupts from A8 and not from the SoC mailbox ( http://git.ti.com/pru-software-support-package/pru-software-support-package/commit/69805828df0f262fb60363c2db189d1b8d0b693c ) . This new implementation hasn't been pulled by RCN yet and is not available even in the latest kernel image 4.4.12-ti-r30. This change well break the older builds ( though not too severely I guess ) as the interrupt number ie the system event number for the PRUSS changes and thus the mapping needs to be changed as well.

2. Testing clocks

I was able to do some testing with the PRU :

http://postimg.org/image/6eysheu9j/
http://postimg.org/image/lhb0s3et3/

Out of the two pictures, one of them is showing the approx frequency that was achieved by using as  __delay_cycles(1) command between __R30 toggle commands.
As I discussed with, Alex Hiam, The pulse shape and the voltage measurements might not be very accurate because of low quality probes, but as that is what I got issued from the college. That is only what i can get my hands on.
Please suggest me on what to do next on this.


3. Firmware for inter PRU communication
As to complete this part, I was looking into beaglelogic's firmware and was trying to port it to the newer rpmsg framework based firmware and I believe, I have understood almost all what is needed to be done. So as its already known that in beaglelogic, PRU1 one does the sampling part and stores the data into the buffer. It then interrupts PRU0 when the buffer is ready. PRU0 then writes this buffer to DDR.

So, to port it to rpmsg framework, the code for PRU0 will have to be re-written completely. This will be done by keeping the interrupt mechanism between the PRUs intact. But then, rpmsg framework too is based on interrupts and after diving in the code, I was able to see that its the interrupt 60 ( the mailbox interrupt ) which is routed to HOST0 of the interrupt controller and thus will be received by PRU on bit 30 of R31. The interrupt from PRU1 in beaglelogic's code is also routed to host0. So to distinguish between the two interrupts, we can either route one of them to different a host, or can check the system interrupt status register ( SECR1-SECR2 ).
 
While investigating, I also found the remote procedure call approach for PRUs ( https://github.com/RobertCNelson/linux-stable-rcn-ee/blob/4.4.11-ti-r29/drivers/rpmsg/rpmsg_rpc.c ), which is also based on RPmsg framework. I think it can be interesting and useful for this project. 

Next Week:

Tasks for the next week:
1. Porting beaglelogic firmware to use rpmsg framework
2. Diving into remote procedure call approach and if useful develop and lkm for it.
3. Bringing up the developed lkm upto the IIO subsystem
4. Start discussing the interface for the parallel_bus driver.


This was all that I could do this week. I am happy as I see progress there. Also, I tried to tally the project progress with the timeline that was in the proposal. It looks like project just lagging by one week. And I am trying my best to get it back in its pace.

Thank you

Zubeen Tolani

unread,
Jun 21, 2016, 11:42:34 PM6/21/16
to BeagleBoard GSoC
REPORT - WEEK 5

Hello Everyone,

It was a slow week for me. Slow in the sense that I was slow in doing the things that were required. As a result, not all the tasks were completed. It was mainly due to following reasons:

a. I have completed 2 posts in this blog - https://zeekhuge.github.io . It involved understanding markdown, adding contents and all that was required. So it took me about 2 days to get all this done.

b. The ADC EVM issue was also time consuming. I had to research about the form, call fedex customer service literally 25-30 times. And then called to each and every fedex offices in Mumbai I could find contact number of. So I am counting it as 1 day.

c. My father came here (I am in college hostel) to meet me and it was Father's day, So I was with him all the time that day. Count it as 1 day.

d. Further there are two different firmwares that I have developed and have studied a bit on IIO drivers so all this accounts for the rest of the days in the week.

Last week :

Tasks for last week were:
1. Porting beaglelogic firmware to use rpmsg framework
2. Diving into remote procedure call approach and if useful develop an lkm for it.
3. Bringing up the developed lkm upto the IIO subsystem
4. Start discussing the interface for the parallel_bus driver.


1. Porting Beaglelogic fw and rpmsg framework

Though the I have not used BeaglLogic's code, but I was able to develop

a. firmware for PRU1, such that PRU1 interrupts PRU0, in every one second.
b. firmware for PRU0, such that PRU0 messages ARM using RPMsg, whenever it gets
interrupted by PRU1.

So in all, its the basic fw for BeagleScope. I have to clean up this code and will push it up on github then.

I have also developed a blinky on PRU1 using inline assembly. So now, I have understood how to integrate PRU C and PRU assembly.
https://github.com/ZeekHuge/BeagleScope/tree/master/examples/firmware_exmples/PRU_inline_asm_blinky


2. Diving Into rpc and bringing up the lkm to IIO
This part remains undone. I have started to read about writing IIO drivers and will get it done soon.

4. Start discussing the interface for the parallel_bus driver.
I wasn't able to start discussion about the parallel_bus_driver, as I haven't reached that point yet, but I have started to discuss about the PRU fw, and most probably a fully functioning fw will be done by the next week. It would have all that we need for BeagleScope.
So, the plan is to have two different functions for sampling, both defined in assembly:

a. The first function will be sampling at the highest possible rate, and will be non-configurable. This is to get the maximum sampling rate by avoiding the waste of cycles in configurable 'DELAY' logic.

b. The second function will be used when the required sampling rate is less than the MAX
sampling rate. In this case, we will have enough time to use some of the PRU's cycles to get configurable 'DELAY' logic in between each sampling instruction.



Also, I would like to bring under your notice that the latest kernel now (4.4.12-ti-r31) has the newer RPMsg drivers. These drivers use A8 INTC instead of mailboxes to interrupt the remote cores.
As a result, there needs to be made some changes in the PRU fw too. The earlier examples that are in the BeagleScope repo use mailboxes and will have to be ported to work with newer RPMsg drivers.


Next Week:

Tasks for the next week:
1. Developing complete fw for BeagleScope.
2. Diving into remote procedure call approach and if useful develop an lkm for it.
3. Bringing up the developed lkm upto the IIO subsystem
4. Start discussing the interface for the parallel_bus driver.



Thats all for this report. Mid-evaluations have already started , hope I will be able to make another report next week :P .
Just kidding. Its mentors responsibility, so not my concern at all. I have been doing my work and I believe my mentoring team.
 
Thank you

Zubeen Tolani

unread,
Jun 29, 2016, 12:16:59 AM6/29/16
to BeagleBoard GSoC
REPORT - WEEK 6

Hello Everyone,

So finally, I have passed my mid-term evaluations, and I would really like to thank all my mentors. Thank you.

Okay so report; actually I need help. Help, not with a technical issue, but with the overall project. Its going too slow for last 2 weeks, and I dont actually know why. I mean I do work, like making example for pru<->pru<->arm communication and porting all examples to new RPMsg and then, making the basic firmware code that can do sampling at variable frequency. But still the main tasks do not seem, to progress much. I am really getting a lot worried about this. Please help me with this in any way you think will be right. If you think I am too lazy, please scold me. If you think the task is just too much, please help me to break it down or you think I am keeping a lot of tasks in one week, please help me to reduce the number of tasks. I always believe I am bad at management-kind-of things and I really need help for this. 

Last week :

Tasks for last week were:
1. Developing complete fw for BeagleScope.
2. Diving into remote procedure call approach and if useful develop an lkm for it.
3. Bringing up the developed lkm upto the IIO subsystem
4. Start discussing the interface for the parallel_bus driver.

1. Developing complete fw for BeagleScope.

So as of now, I have an assembly program that can have variable sampling frequency : https://github.com/ZeekHuge/BeagleScope/tree/port_to_4.4.12-ti-r31%2B/firmware. I have added macros to manage interrupts too, but there are some compilation errors which I will probably be able to resolve before the meeting. I have also developed inter pru and arm communication (at the same time using RPMsg) example for new RPMsg kernel : https://github.com/ZeekHuge/BeagleScope/tree/port_to_4.4.12-ti-r31%2B/examples/firmware_exmples/pru1_to_pru0_to_arm

  • So for PRU1,which would be sampling the data, we really need ASM code to make it fast. Going with inline-asm was my first choice, but then according to the compiler's docs, it used the RX registers for various purposes like stack and etc. This can easily conflict with the working of ASM sampling code and thus corrupt the data. Therefore I have decided to go with complete ASM code. As of now, I have used C file to declare main function as extern and then provide its definition in ASM file. That was because, I was unable to understand a way of providing the resource table to the ASM file. I think I have figured it now and will port the code to complete ASM code soon.
  • Further, the core0 will write a 32 bit data into shared RAM and then will interrupt core1. Core1 will load this data into its register and use it as sampling_config. The first 16 bit of the data will be the delay between two samples, next byte will be the sampling width, and the last byte will be reserved plus stop/start bit.

2. Diving into remote procedure call approach and if useful develop an lkm for it.
I tried to look into it and understand the remote-procedure-call driver. So what it basically does is, it allows the PRU to publish its own functions to the userspace. The kernel driver does this by asking PRU about each function is wants to publish. This can be used for making configurations. Though I haven't got it very well, but I am reading the code and trying to get it.

3. Bringing up the developed lkm upto the IIO subsystem and discussing about the bus driver:
I haven't yet reached at this point, and that is what I was saying in the first paragraph. I am really worried. And I seriously need help for this.


Next Week:

Tasks for the next week:
1. Completing fw for BeagleScope.
2. Skeleton pru-parallel-bus driver as a char device driver
3. Bringing up the developed lkm upto the IIO subsystem
4. Start discussing the interface for the parallel_bus driver.



Thats all for this report.

I have received the ADC EVM. Thanks to Jason.

I am really glad to receive feedback from all my mentors. I will be discussing on the "git commit" point and will definitely try to improve on it. Also, thank you for believing on me and letting me pass the mid-evals. That brings more responsibility on me and I really want to stand to it. But I am starting to worry about the pace of the project. I know myself, and I can really work a lot more harder, just need some guidance and help (even if its in the form of scoldings) from you on how to go along with this problem.
 
Thank you

Zubeen Tolani

unread,
Jul 6, 2016, 4:07:01 AM7/6/16
to BeagleBoard GSoC
REPORT - WEEK 7

Hello Everyone,

Well, I was quite low and worried about my progress until the last meeting. And in that meeting, one single word "ZeekHuge : focus", that Michael said, was somehow able to boost me up, and I realized that only 'doing' can solve this. So today the repo is at 106 commits with about 56 commits in the last week itself. Yes, this is not enough to bring the project back to its schedule. But this is enough to motivate me more :) . Thank you Michael.

Last week :

Tasks for last week were:
1. Completing fw for BeagleScope.
2. Skeleton pru-parallel-bus driver as a char device driver
3. Bringing up the developed lkm upto the IIO subsystem
4. Start discussing the interface for the parallel_bus driver.

1. Completing fw for BeagleScope.

The fw is complete : https://github.com/ZeekHuge/BeagleScope/tree/port_to_4.4.12-ti-r31%2B/firmware

As per the current state, the firmware can
  1. Sample 44 bytes of data in one cycle.
  2. Transfer data to PRU0 after each cycle.
  3. Utilize all 3 scratch pad banks in cycle starting from bank0.
  4. Sampling frequency can be configured from userspace.
  5. Sampling can be stopped and started from userspace.
I have written a small test.patch too, that can be applied to the code and then code will be ready to be used for testing purpose. The patch basically replaces the MOV instruction, that takes input sample, with LDI32 instruction (Load immediate 32) and loads an immediate value defined as FAKE_DATA. It also changes the clock signal. After the patch the clock signal just toggles for each sample taken.

I had some concern about the duty cycle of the clock earlier too, I asked on the IRC, but not many people were present there (which is completely fine), finally after the fw was ready, I discussed it with Michael and it turns out that I will have to get either 50% duty cycle, or make it configurable without loosing extra clock cycles. I have opened it up as an issue and it will be resolved soon. https://github.com/ZeekHuge/BeagleScope/issues/1

The configuration part - To change sampling frequency and to start/stop the sampling, we need to send 2, 32 bit long messages from the userspace, ie using the /dev/rpmsg30 device file. This can be done anytime, even when the sampler is running. The first message will be the required delay value between the two samples. This value should always be even and greater than 7. There is no need to subtract the clock delays and other things before sending this message. Just send in the exact delay needed between two consecutive samples, and code will do all for you. 

Further, while testing the fw, I had to go through compiler implementation of C on PRU0. We need C to use RPMsg, Though I was able to extract the compiled asm file, by changing some of the compiler flags -  https://gist.github.com/ZeekHuge/68458821a6bbad52f31f9e9eedb771df . Working around such compiled asm files will be very difficult way to do the required task.

The problem is that, the intrinsic __xin() function provided by the compiler allows a maximum of 44 bytes of data to be transfered from the scratch pad banks to the internal registers, for one call - https://github.com/ZeekHuge/BeagleScope/blob/port_to_4.4.12-ti-r31%2B/docs/clpru_and_C_usage.notes#L264. This is probably because the registers are not all available to us  -  https://github.com/ZeekHuge/BeagleScope/blob/port_to_4.4.12-ti-r31%2B/docs/clpru_and_C_usage.notes#L146

There is one more limitation. The RPMSg framework interrupts ARM after every message it sends. So an interrupt to the MPU after every message of 44 bytes. This freezes or makes ARM very slow at higher frequency (ie lower delay message value).

A solution to this might be to first save sampled data from PRU1 into the shared RAM, or just in some variable which, I guess will automatically be saved into data RAM or shared RAM or both. And then transfer the data using a full RPMsg buffer.
This again has 3 problems:
  1.  I am using shared RAM to share the configuration data. Writing to shared mem in C cant be controlled, as where, in the shared mem the data will be written - http://git.ti.com/pru-software-support-package/pru-software-support-package/blobs/master/examples/am335x/PRU_access_const_table/PRU_access_const_table.c#line48. So this might overwrite the configuration data.
  2. The maximum size of the RPMsg buffer is 512 bytes. Its not something in the PRU implementation, that could easily be modified, but its defined in the virtio_rpmsg_bus - http://lxr.free-electrons.com/source/drivers/rpmsg/virtio_rpmsg_bus.c#L109. So we will have to interrupt the ARM after 512 bytes, for a sampling frequency of 15Msps, that will be about 29000 interrupts in one second. I don't know if the ARM will be able to handle this.
  3. This might not be a problem, I just don't know if a transfer from shared_mem/data_mem to the ARM will be fast enough to be able to do the required data transfer.
So this part needs some discussion.

2. Skeleton pru-parallel-bus driver as a char device driver & Bringing up the developed lkm upto the IIO subsystem.

Yay ! I have started working on the driver. And today, there was a very important learning - "How missing new line character in printk statements can waste 3 or more of your hours" ;) Thanks to Michael and Hunyue, that it didn't exceed 3 hours for me. I wouldn't have really cared about it.

So I have the skeleton driver that registers itself to the rpmsg bus and waits to be get probed. There are some errors in the driver now. I will surely be able to resolve them before the meeting.
The idea is to develop one single driver for now, that will do all the things. And then later break it down into parts. This will help testing the code as we will always have something that works. This driver will have :

  1. PRU communication part - So this will be based on RPMsg API calls. I already have developed a client RPMsg driver and it works completely fine. https://github.com/ZeekHuge/BeagleScope/tree/port_to_4.4.12-ti-r31%2B/examples/kernel_examples/n-blinky/module . And I believe that will make this kernel developement a bit easy for me. 
  2. The ADC driver part. I tried to find if there is already a driver for the ADC part I am using. But there is nothing on that. So this driver will also have the ADC device driver part in it.
  3. Registering the driver to the IIO subsystem. This will involve adding raw read/write functions and then the device specific structures.

About the remote procedure call - I didn't dive deep into it. But now I think its not needed. The RPC approach is pretty complex and uses up more resource on PRUs. It would involve defining functions and various calls, which will again use those registers as indicated in the above link. And I think it will be better to keep PRU0 free from other complex tasks, so that we could use it to transfer data to the ARM. Also, why to use such a complex approach (though it looks interesting) when 2 x 32 bit messages do the required task (it can further be converted into 1 x 64 bit long message).  

3. Start discussing the interface for the parallel_bus driver.

Yes, this part again remains untouched. But I am full of energy now. I will get here soon.


Next Week:

Tasks for the next week:
  1. Completing the driver.
  2. Starting discussion on the interface for the parallel_bus driver.
  3. Time reserved for improvements in the fw.

Thats all for this report.

Phewww ... it got quite lengthy. And sorry for submitting it late this time.

I also tried to write better commit messages. Credit goes to Steve Arnold. His suggestion that commit messages should help you when you return back to your code after 1 year to remove a new bug, really helped.

Thank you

PS : We can use scratch pad banks to share configuration data too, just figured it out. So, that problem - "C implementation overwriting onto the shared mem" is solved with this I guess.

Zubeen Tolani

unread,
Jul 13, 2016, 1:44:37 AM7/13/16
to BeagleBoard GSoC
REPORT - WEEK 8

Hello Everyone,

Wow ! 8th week report ! Time is moving pretty fast ... !
Anyway, this time, I am not going to make any comment about the last week. Would just say that I really need to work hard ... harder than I am already working.

Last week :

Tasks for last week were:
1. Completing the driver.
2. Starting discussion on the interface for the parallel_bus driver.
3. Time reserved for improvements in the fw.

1. Completing the driver:

Till now, I have been able to get the driver probed whenever a rpmsg-channel named 'beaglescope' gets created. Now since this driver will contain all the iio_device_driver code and the rpmsg_client driver code, I think there should be two ways to get this driver probed. One when the rpmsg_channel named 'beaglescope' get created (this has already been implemented) and the other when the adc is plugged in.
I read other ADC driver codes and found that they register the device name to their associated bus, and that bus driver then probes the device driver.
In our case, there can be two ways to implement this :

  1. Using a device tree overlay. I am already somewhat familiar with this device tree overlay. But if we use this approach, we will have to specify the gpios and their mux settings to route them to the associated PRU-pins. This will probably result in a conflict with the universal cape that is already present and loaded onto the newer kernel images.
  2. Use the EEPROM present on the board and use BBB's I2C bus to probe the driver. This approach seems more interesting to me, as its like plug and play, and it is what other iio_device_drivers do. So can this be done by registering device name to the I2C bus driver ? I am not sure how this works internally. Does the I2C bus keeps on checking reading on its I/O pins every time ? Or it uses some other mechanism to do this ?

As far as the current state of the driver is concerned, it actually took me time to understand the IIO data structures and how to relate it with the ADC device that I have. I have got some understanding but its still not completely clear to me. I had some doubt and Michael helped me with it. I will keep asking as I move along.

As of now, The driver gets probed, registers itself to the IIO subsystem and the iio sysfs bindings do appear according the channel specifications (https://gist.github.com/ZeekHuge/c0334c14d33ce62d6d27552a18073b01). I am working to add the read raw methods to the driver. I have already added the read_raw methods actually, but it isnt working and was getting late to write the report so I left it there.


2. Starting discussion on the interface for the parallel_bus driver :

Ahhh ... well, I haven't officially started to discuss about the parallel_bus driver, but I have started to gain understanding about how to go along.
Okay so what I am getting out of all the work I have done till now is :

Virtio framework  is used to create virtual devices and buses. So the virtio_rpmsg_bus is actually a virtual bus over which data is transfered. Now the rpmsg client driver uses a structure called rpmsg_channel. This rpmsg_channel (aka rpmsg device) is a virtual device that is connected on the vitio_rpmsg_bus (a virtual bus). So a client driver actually communicates to this, rpmsg_channel device , which further communicates to the pru over the virtio_rpmsg_bus.

Now for our purpose, the parallel bus driver that we need to develop has to be like virtio_rpmsg_bus, and it shouldn't be like a rpmsg client driver, which would just communicate to the rpmsg_device. I think this will be unnecessary overhead and not the right approach.

So with the limited knowledge I have, I think we will have to do some modifications (  probably minor ones ) in the virtio_rpmsg_bus driver to finally make it a pru_parallel driver. This would also provide us with the opportunity to increase the size of the buffers, that is limited to 512 byte in virtio_rpmsg_bus.

Though we can do it later and go on with the rpmsg_client approach to implement the pru_parallel driver for now.

Please let me know your thoughts on this.


3. Time reserved for improvements in the fw.

Okay so the fw had some limitations. The most imp one was about its duty cycle, as also mentioned here ( https://github.com/ZeekHuge/BeagleScope/issues/1 ).
So I have removed the redundant code form the fw source and some of the unused DELAY macros, and have added another DELAY macro that would replace the one already being used.
The new macro is : THE_DELAY
macro already being used : DELAY_SAMPLE

(please refer to the code (https://github.com/ZeekHuge/BeagleScope/blob/port_to_4.4.12-ti-r31%2B/firmware/main_pru1_def.asm) if the explanation below seems out of context )

The least delay that we can have using DELAY_SAMPLE is of 2 cycles, but with THE_DELAY macro, its of 1 cycle.
Now, The plan is to include this THE_DELAY macro in the TAKE_SAMPLE_8 macro like this :

CLK_TOGGLE
THE_DELAY
MOV RX, R31
THE_DELAY
CLK_TOGGLE

Further, all the occurrences of DELAY_SAMPLE macro will be replaced by the THE_DEALY macro. This will result in a completely configurable clock duty cycle, without any loss in the max configurable sampling rate that can be achieved (this code will be able to sample at about 28MHz ) 
I tried to add these changes, but the code wont compile as it becomes large to fit into the code memory. I went back to the PRU manual and found this MVIx instruction. I tried to use it, but the instruction is a bit 'awkward' as it works sometime, and do not work other time. I am working to understand how to use it. Using this instruction will probably decrease the size of SAMPLE_CYCLE_8 macro, atleast that is the plan, and then we will be able to use THE_DELAY macro.

I have also added two modes of sampling.
RAW_READ : this reads one single sample, instantaneously and sends this 32 bit sampled data back to the kernel just once.
BLOCK_READ : This is what the PRU was already doing, sampling data continuously, until its interrupted and sending it back to the kernel in blocks of 44 bytes at a time.

To introduce all these modes and the configuration related to clock duty cycle, it was required to increase the size of configuration data that the kernel sends to the PRU. Earlier, it was just 2*32 bits, now its increased to 3*32bits


- BONUS ;)

I worked out to get the hardware setup. I couldn't get the standard things from the local shop, so I made them myself.

- The new BBB pins were fried up, due to wrong resistor values. I got old one from my college. Had a 2A ,6V power source (it was rated 5V but was giving 6V and BBB wasn't booting up), so used a voltage regulator to convert it to 5V.

- I have never seen such power pins, as where there on the ADC. What I just did is, soldered them to a wire with female connectors on the other side.

- ADC needs to be kept safe (Though I love blowing things up ;) ). So I have got a variable voltage regulator as ADC's power source and I will use it at 2.5V ( and will increase only if ADC needs ) to be on the safe side.

- I have got this arrangement of male header pins on a perf boarrd, at positions where the PRU pins are routed out, and it fits nicely on the BBB.

- Finally, there is that female connector, to connect to the ADC output pins.

Getting all this done took me 2 days. And then I returned back to the software. I will do same the next week, but I wont give it more than 2 days.
 

Next Week:

Tasks for the next week:
  1. Completing the drive.
  1. Starting discussion on the interface for the parallel_bus driver.
  2. Time reserved for improvements in the fw.

Thats all for this report.


Thank you

Zubeen Tolani

unread,
Jul 20, 2016, 3:55:18 AM7/20/16
to BeagleBoard GSoC
REPORT - WEEK 9

Hello Everyone,

This time, its going to be really short, That is because I didn't do anything. Actually I took this week off as a break.

It was not already decided. Actually the college is back at its functioning now, and we had some work there at the college that used up the first 2 days of my last week, that is, Thursday and Friday.

My sister has just joined a college . I Had to travel a bit to help her with all these new things for her . And it used up further 2 days of the last week, like some part of Saturday, Sunday and Monday.

Finally when I was back. I decided to take a break this week.
I don't actually know what will be your reaction, and therefore, I was afraid of telling this along the week, and face to face on the IRC.

During this time, though not directly related to the BeagleScope project, I worked on my website. It was previously hosted on Github pages. I have now got a server for it. I have got an SSL certificate too and registered the website with Google to index the pages.

I have also added content to the website. I was actually targeting for 5 posts. Two of which are ready and posted
https://www.zeekhuge.me/post/ptp_docs_commands_and_tools/
and
https://www.zeekhuge.me/post/ptp_blinky/

I have written some content for 2 more posts but, I am finding it a bit difficult to organize them. It will probably be done by tomorrow and I will be definitely working from the Next week.

Thank you

soapy...@comcast.net

unread,
Jul 22, 2016, 1:38:02 AM7/22/16
to BeagleBoard GSoC
I checked out your new web page.  This is very good material, and it will help me along nicely with my own project using remoteproc and friends.
Your contributions are outstanding!  I'm looking forward to future reports.

I agree the PRU is quite challenging to work with!

Regards,
Greg

Zubeen Tolani

unread,
Jul 23, 2016, 3:46:39 AM7/23/16
to BeagleBoard GSoC
Hi Greg,

Thank you :) I am glad that it helped. There are more topics that I would like to write about, but as you can already see in the reports here, Beaglescope project needs a lot of working.
But anyway, Thank you for your appreciation. It really helps.

Zubeen Tolani

unread,
Jul 23, 2016, 3:47:11 AM7/23/16
to BeagleBoard GSoC
REPORT - WEEK 9.5

Hello Everyone,

My last report was not up to the mark, as it didn't tell anything about my steps further. As a result, Abhishek asked me to submit a mid week report. So here it is.


Last 2 days :

In last two days:
  1.  I have resolved issue #1 regarding configurable duty cycle while sampling.
  2. Michael helped me testing the firmware. The test basically involved sending configuration data from user space to the firmware and test whether the sampling frequency and the clock functions as it should according to the configuration data. The test was successful very precise.
  3. As already reported, the CPU stalls when we switch to higher sampling frequencies.
  4. I tried getting data out of the ADC. Michael helped me along the process, but we were unable get the correct driver circuit. Hunyue then pointed a mistake in the driver circuit, but till then I already removed the shunt on the cap C12. To get it back there, I was waiting for the next day, and get it done by a precise tool, rather than my old soldering rod.
  5. I was trying to couple the PRU firmware with the drivers, but I am still unable to understand why is it not working. I will dig in more into it and get it done by today.
 
This week :

An overall goal for this week is to get the parallel_bus driver separated from the main driver and have well defined interface. For the interface part, I will have to take a look at the SPI and I2C bus interface. The APIs that they export for various things. How I am planning to go along:

  1. I will be using an rpmsg_client driver approach to implement the parallel_bus driver. So it will be sitting on the virtion_rpmsg_bus and thus talk to the PRUs.
  2. On the Kernel side, this driver will provide APIs to:
  • Boot the bus
  • To shutdown the bus
  • Set the configuration of the sampling process

This driver would be a separate entity from the main driver. Though during the transition, it will still be functioning as the main driver did, by using the declared APIs.

So, that will be the goal this weak.
 
Thank you

Zubeen Tolani

unread,
Jul 27, 2016, 10:42:49 AM7/27/16
to BeagleBoard GSoC
REPORT - WEEK 10

Hello Everyone,

The report.

Last week :

1. Completing the driver:

I have completed the driver. Some tuning, minor testing and improving the formatting is whats left. Therefore the completed driver is actually in the wip branch.
The working of the setup is as :

The driver gets probed when a rpmsg_channel named 'beaglescope' is created . This channel is created by the virtio_rpmg_bus as soon as the beaglescope/firmware is loaded onto the PRUs. The PRUs then wait for configuration data from the driver.
On the driver side, after getting probed, the driver registers itself to the IIO subsystem as IIO_VOLTAGE device. This basically means that the output will be of 'voltage' type. Further, the driver maintains a beaglescope_state structure, that basically has the data about the current instance of the device.
The driver registers only one channel to the IIO subsystem. The ADC board can actually output data in 2 formats:
  1. 2's complement
  2. Offset_binary
I have chosen the offset_binary form and then have exposed only that data format through the channel.
The driver supports two different modes of operation:
  1. DIRECT mode - in which, every data output is an instantaneous value.
    The data when captured using in_voltage0_raw is actually when we are working in this mode. Whenever in_voltage0_raw is read, the driver just sends configuration data associated with the RAW_READ mode to the PRUs. The PRU takes an instantaneous value and send thats value back to the driver. The callback associated with beaglescope rpmsg_channel caches this data inside the beaglescope_state structure. To sync this process I have used wait_list_queues. That is, after the configuration data is send to the PRUs the thread sleeps inside the wait_list until its interrupted back by the callback thread.
     
  2. BUFFER_SOFTWARE - the perform buffered capture.
    For this, a buffer has to be attached to the iio device. This is done by specifying the scan elements in the channel specification structure, and use some APIs to attach the buffer to the iio device. This buffer is actually a FIFO. The driver uses this buffer to save data during buffered capture. For the scan elements, I have specified following characters:
    • sign = u (unsigned)
    • realbits = 10 (as the adc output is 10bit wide)
    • storagebits = 16 ( the PRU cant actually sample 10 bits, it has to sample either 8bits or 16bits, so 16 bits in this case)
    • shift = 0 (this is because the data is ready to be used without any shift )
    • endianess = IIO_LE ( little endian, as that is how the firmware sends the data )

    Usually, IIO device triggers are used to start buffered capture. The triggers used are actually per data sample triggers, but in case of this device, there is no such 'per data sample' trigger. The data is rather in form of blocks. So there is no triggered capture.
    Also, normally the process of starting triggered_buffer capture is : specify the trigger name and enable the buffer by writing 'echo 1 > /sys/bus/iio/devices/iio: device0/buffer/enable'. But since we have no triggers, buffered capture can be started just by enabling the buffer.
    The data from the device (pru) is in the blocks of 44 bytes, but the iio_push_to_bufffer() API can push only one data sample per one call. As a result I have used a loop to transfer the complete block of 44 bytes into the buffer, using iio_push_to_buffer() API. I have been discussing with Jonathan about this and he has been guiding me throughout the process. He has suggested that we will ultimately have to use DMA to get the data, and this use of iio_push_to_buffer is temporary.

The driver IIO also exposes in_voltage0_sampling_frequency and the driver supports sending variable frequency to the PRUs, but this part needs some improvement. The configuration data that is sent to the PRUs actually contains 'number of PRU cycles to delay' , and not the frequency, so, I need to improve the calculations part in the conversion process, it is mostly working, but the resulting frequency is not actually the given one, this is probably because we only have fixed point calculations, so I need to increase the accuracy by improving the multiplication factor.

Further, though the pru firmware supports variable clock duty cycle, for the sampling, I have used ~50% duty cycle. Actually I haven't been able to find a way to expose this feature to the userspace. Can it be like a different driver that manages the clock ? Not sure what to do, so just used 50% duty cycle.

2. Getting data out of the ADC :

Finally, after a lot of trying, I was able to get data out of the ADC. Thanks to Hunyue and Michael. They helped a lot (read 'they actually did this'). So here is the final circuit that I have used for the clock driver :


Before actually connecting the output of the driver to the ADC clock pin, I was trying to get the voltages correct. At first even before making the circuit, I was worried that the output should not exceed 2.5V as the ADC IC schematic said that the clock should be less than 2.5V. Michael then pointed out that there is a buffer on the clock pin and it can tolerate upto 3.6V. After I soldered the circuit, I was actually getting a voltage of about 2.45V . Then, I was worried that the buffer needs a higher voltage to give LOW output (buffer is actually an inverter ), and then I just connected and checked the output, surprisingly it was LOW. Finally I was able to get it working after lot of, I would say, playing around. Not to mention, there were numerous wrong connection cases.
I have not tried it with the beaglescope code yet, but the code that I used was very similar and was on PRU1 (the one that beaglescope uses for sampling process). I am very happy after Hunyue said " those numbers look reasonable", yes these were his exact words :D

To get all this working, I had to remove the capacitor (C12 on the board schematic) as we are using square wave and not a sinusoidal wave.

Next week:

-

I am leaving this section empty for now, as I need to do some testing with the beaglescope_driver and check the bottle necks and the requirements. As a general task, I will be working on defining and implementing the pru_parallel_bus driver.
I would request the mentors to give me some time and then I will be submitting report 10.5, latest by this Friday, describing my steps ahead.

Thats all for this report. Thank you.

Thank you

Zubeen Tolani

unread,
Jul 27, 2016, 10:47:46 AM7/27/16
to BeagleBoard GSoC


The circuit Image in the last post is not visible, so I am just trying to insert it again. Not sure if it will work this time.






Zubeen Tolani

unread,
Aug 3, 2016, 10:06:42 AM8/3/16
to BeagleBoard GSoC
REPORT - WEEK 11

Hello Everyone,

And .. here is the report :

Last week :

1. Bugs and Improvements:

So, This week I did all those things that were the left in the driver and it is finally in the main branch. While getting the driver into the main branch, I restructured most of the tasks into relevant methods. The final setup was working very well, with just 2 problems :
  1. There was this bug in the code: https://github.com/ZeekHuge/BeagleScope/issues?q=is%3Aissue+is%3Aclose
    This bug was not allowing to set certain frequencies and was causing the board to stall.
    This was really nasty bug. You can see in the comments in that issue, it was behaving very odd and in fact I have not added most of the awkward things in the issue. So finally somehow searching for the mistake, I realized that its something related to the rpmsg callback and the buffers. Somehow, I found that the buffer was not getting filled up. And then it was that I focused on the buffer part.
    Actually, the buffer-specifications ( the scan elements) I was specifying in the iio_chan_spec structure were setting the buffer for a 16bit wide sample-reading. While when I was actually transferring the data inside the rpmsg callback to the iio buffer, I was using u8 *pointer, and the loop was going on 'len' times where len is the size of data ie 44 here. I don't actually know how this was causing the the ARM to stall and all that odd behavior, but after making the correction, It was all working. And thus the issue got closed.
     
  2. The next problem was that at higher frequencies, PRU was interrupting the ARM very frequent and hence causing the system to stall. So, we had the limit of 1MHz sampling rate.
    Now this was a problem because we could use larger buffers on the PRU side, but that would have resulted in slow transmission rates. This is because the PRU will basically have to save all this data into its far memory storage. And reading data from there will be definitely slow. While on the kernel side, we already had larger buffers, but were unable to use it. As I reported earlier, the virtio_rpmsg_bus supported  512 bytes of buffer, including the message header, which is about 16 bytes. Also, each buffer is kicked once, so we  were just putting 44bytes in a buffer that was capable of ~(512-16)bytes of data, and then kicking it every time.
    The solution to this was to some how make the PRU write those 44 bytes of data, about 10 times and then kick. But this was not allowed by the existing rpmsg APIs. So I went into the code and added a method called rpmsg_send_large_buffer() to make is do what we need.
    Now the PRU writes 440 bytes to the rpmsg buffer and then generates a kick. This increased the performance and now, we have the highest sampling rate of 20MHz. This is actually the limit of the current PRU firmware with 50% duty cycle.
    In fact while I was working on this, the code was really giving absurd output. I was again searching for a mistake in it, as the other example with different code that used rpmsg_send_large_buffer() was working perfectly fine. Finally when the #2 was resolved, this code started working fine.
Finally with all this going on for about 3 days, I had the jump from 1MHz to 20MHz. But now kicked in the other limitation. This was about the buffers.
The IIO subsystem do not have any API that transfers data from one buffer to the other all together. They only have API that can be used to transfer single reading into the buffer. So, for this to work, I have used a loop to transfer data into the iio buffer, in the rpmsg callback. This is a slow point and I am not actually getting data out in the IIO buffers at high frequencies like 10MHz. I tried increasing the size of iio buffer, some times with a sane value and other times with an insane value, but that didn't help either. So whats the solution ?
Well, DMA for now is out of question as we already are burning up one PRU using it as a DMA. So what I think we can do is, add support for user-given-buffers into the virtio_rpmsg_bus and then provide the callback with a reference directly to IIO buffer. I tried reading the virtio_rpmsg_bus source, but its filled of vrings and all that are implemented over the buffer, so I am not sure how to actually add the user-given-buffer support. Anyway, probably a post-GSoC task.
 
2. Parallel interface APIs :

While I was restructuring the beaglescope_driver, my aim was basically to divide it into two parts, but in the same source file. So I wanted to make the functions in one part independent of the other. It took me about 2 days, but I wasn't able to completely achieve it. The idea was to first have a single source with independent functions and structures, and then to transfer those methods and structures into a new file that would EXPORT those methods. I started to read about the IIO subsystem, SPI and I2C buses. But I am still having difficulty in conceiving how to go with it. Though I have added the parallel_interface driver code, in parallel_interface_wip branch, but its too basic, and I have just started. So this will either need more reading, or more structured approach. I should probably define a minimal structure on paper and then try implement it and also should start with a bad code, not worrying about the standard way of implementation.

The overall idea of the interface I have is that it wont be based upon the query-response approach, though this can be implemented, but will be only for slower data rates. It should rather be a callback approach. For now, it will use a loop to transfer data into the iio buffer, but  once we have the API, we can change the underlying implementation. Further, It should be able to tackle more than one device together. Though on the PRU side, only one device at a time. I guess that will be easy as each of the adc driver will have its own instance of the parallel_interface_driver. The next thing is about probing the drivers. So the parallel_interface driver should be probed when 'parallel_interface' named rpmsg channel is created by the PRUs. Now this driver will register itself as a bus in the system, and then the iio driver or simply the adc driver would register itself on this bus. Further, the adc driver should be probed when a device-tree-overlay for this adc is loaded.

 
Next week:

- 1 day : Data integrity check, and just a look into the virtio_rpmsg_bus
- 2 days : A structure of the APIs for parallel interface.
- 3 days : Implement the APIs
- 1 day : Tests and all

Thats all for this report..

Thank you

soapy...@comcast.net

unread,
Aug 4, 2016, 7:09:24 AM8/4/16
to BeagleBoard GSoC
Awesome work!  I have been experimenting with the PRU RPMsg and I think you are seeing some of the same behavior I have observed.
Although you are actually figuring it out!  This is the first example I have seen of pulling data through the RPMsg mechanism at very fast rates.

I will be studying your work and trying to understand it myself.  I hope you can translate this to better understanding of the Remoteproc/RPMsg
to the broader Beaglebone community.  It would be great to see more projects with the PRUs.

Keep going, outstanding results!

Regards,
Greg

Zubeen Tolani

unread,
Aug 10, 2016, 10:44:56 AM8/10/16
to BeagleBoard GSoC
Hello !
Not a report, just a request mail :

I need one more day to get this done and will then submit the report.

For now, My college recruitment is to start soon and being a member of the college Training and Placement office, it has been keeping me very busy.

However, I have been trying to develop the interface, and even did develop 2 APIs but it was not upto the standards and was very rough. Actually I wasnt able to understand a lot of things.
Finally realized that I need more of theoretical knowledge and started reading "Linux device driver edition 3".

I am about to complete the required sections and things are really more clear to me know.
Infact I was expecting that I will be able to complete reading book and then will start developing the driver, before the meeting, and then will send the report.

But that seems to delay a bit and therefore this request mail.
Please allow me to send the report the next day about same time, I am confident enough that report will be showing some good progress.

Thank you

Zubeen Tolani

unread,
Aug 17, 2016, 9:06:14 AM8/17/16
to BeagleBoard GSoC

REPORT - WEEK 13

Hello Everyone,

So the last weekly report. That brings tears :) it was a routine to write weekly reports ( Okay, sometimes not reports but at least something ;) ) for last 12 weeks.

So the current status :

Drivers :
After reading a lot of code, documentation and ldd3, finally have understood how the device and driver bindings actually work, straight from the core ,right up-to the device-driver.
This has been challenging and really difficult. I have been asking for help everywhere and been doing lot of testing, trials and debugging through kernel oops.

Doing this in the device driver model was important. That is, having different parts of the whole software stack, on different drivers and registering themselves through APIs. It was difficult as it required precise and in depth knowledge of what is going on inside, for example - missing a single instruction that 'gets' a kobj or 'puts' a kobj can generate long long oops and you do not know what the APIs do internally. Then, tracking it down is again another challenge.

So as of now I have :

  1. The pi_bus driver. This driver first registers itself as a rpmsg-client driver and waits for 'beaglescope' channel to be created. Once the channel is created by loading the associated firmware onto the PRUs, the pi_bus driver gets probed and in its probe, function further registers itself as a platform-driver to the kernel. It has to be platform driver as it is the lowest driver in the stack, and the parallel bus host device is not self-discoverable. This driver detects the pi-bus host device and calls the pi_core_register_host() API.

  2. The parallel_interface driver. This driver is the core-bus driver. It first registers itself as a bus driver with help of 'struct bus_type pi_bus_type' structure, specifying all the required methods present in the driver. It then provides with the APIs to register the host-device and the device-drivers. To register host device, the pi_bus driver (or any platform driver) calls the pi_core_register_host(). As the implementation of this API, the core-driver allocates a pi_bus_host structure and initializes it with appropriate values (like the associated of_node, modalias etc) and then registers it on the pi-core bus. So this, pi_bus_host object becomes the first and the parent device on this pi-bus. So, all other child devices that get then registered are actually child to this device.

  3. Device registration according to the device tree. Yeah, so here comes the tricky part. Now, the structure of the device tree is simple : there is a root node and then it has its sub nodes. A node immediately inside the system bus (like the fake ocp bus in case of beaglebone black) are usually peripheral nodes. Now, a root node in a device tree is always registered by the OS as a platform-device and can only be served by a registered platform driver, with a matching compatible string. Once the platform-driver is probed, no responsibility about the remaining sub nodes remain with the kernel. The platform driver just probed now need to do everything. So what about the  child of that root node ? Yeah that question kept me busy for a while. Actually, a device is registered as a platform-device when it do not needs to be on a specific type of bus. Based on this rule, the platform-driver registers it's child nodes as other platform devices if required . In this process, the last device that gets registered as platform device is usually the peripheral-device, in our case the pibus0 node. Now, for this pibus0-platform-device, we have the pi_bus driver to serve it. After the host device gets registered at the bus, the core bus driver (parallel-interface driver) then needs to search for all its child node and this time register it as a bus-specific device (that is, non-platform device). The core-driver then tries to compare and match each of its drivers with a device. If a match is found. It probes the driver.

  4. The device driver registration is simple. For now, its just that same beaglescope_driver serving as the device driver. As the development will progress and the functions in the driver are just related to the device-drivers , I will rename the driver according to the board name. The device_driver in its _init method, registers itself to the parallel_interface driver with the help of bus specific device-driver structure.
I have all this stack tested and working. The three drivers work as they should and I have tested it for every error that I thought could be there. Though there are a few more vulnerabilities. I haven't added any protection to register only one host driver, if there are more than one device-tree nodes detected with a matching compatible string. Thats in the TODO list.

It took me long to get this setup working. But I guess it was tricky. And now that this is done, I can proceed to the communication APIs after documentation.

Next week:

For the next week, I will be focusing mainly on documentation. Documenting all the PRU examples and all the parallel-interface software stack I have developed.
The gh-pages branch of the main repository will be having all this and will probably serve the product link. Along the way, I will try to get a few communication APIs declared and working, but the main focus will be documentation.

The final report with a analysis from my side will be done in some time and mailed soon.
Thats all for this report.

Thank you.

Zubeen Tolani

unread,
Aug 17, 2016, 9:07:52 AM8/17/16
to BeagleBoard GSoC
The Final BeagleScope project Report
for GSoC-2016


                                


Prelude
:
Google summer of code 2016 was announced on 13, October 2015, and everyone was excited since then. Further, Beagleboard.org was accepted as a mentoring organization for the GSoC program on 29th February 2016 and I remember getting up at 3:00AM in the morning, looking up for results and congratulating members of Beagleboard.org-GSoC on its IRC channel and thats how It all started.

Content
  1. Proposed Work
  2. Completed Work
  3. Things not done
  4. Things done out of the proposal
  5. Obstacles
  6. Things to make it better
  7. Further development
  8. Final words

1. Proposed work :

  • BeagleScope ( Link to the proposal )
    • Programmable Real Time units
      • firmware to sample data at configurable sampling rate and configurable sampling width
        This firmware had to be developed in the form of 2 different functions/MACROs
        1. function/MACRO that could sample at configurable frequency which would result in highest sampling frequency of about 28MHz
          This function/MACRO has 28MHz as the highest achievable frequency. This is lower than the highest achievable frequency. This can be justified by the fact that the logic that is used to cause configurable delay, actually consumes some of the cycles. That is why we need a different MACRO/function that wont have any configurable delay logic in it.
        2. function/MACRO that could sample at the absolute highest possible rate of about 40MHz.
          This function would be completely hand optimized and have nothing configurable. It would be simple logic to sample data, store it and then transfer it to the other PRU.
        Both of these MACROS/functions were to have configurable sampling width.
    • Linux kernel
      The project has to be developed in 2 steps:
      • Step 1
        A single driver that would manage PRUs as a resource, the sampling process and its interface to the user-space through the IIO subsystem.
      • Step 2
        In step2, the process on the Linux driver side has to broken down into 3 separate drivers, based on the Linux driver model and on the driver developed in step1, registering with each other through the APIs. The drivers has to be :
        1. A platform driver specific to the platform.
          The driver need to have well defined interface for the core-bus driver to send and receive data seamlessly. The APIs, at the same time should have be able to expose different capabilities of the available hardware.
        2. A generic core-bus driver to manage all the data transactions on the bus.
          This driver should be able to utilize all the APIs that were exposed by the platform_driver to provide an interface to the parallel_bus driver to read and write data from the device. Further it should be able to manage different devices on the same bus and be able to set different configuration data required to get data out of the device.
        3. A device driver that would be specific to the adc (or any IIO) device that needs to be attached to the parallel bus. The driver would register itself to the core-parallel-bus-driver and to the IIO subsystem for further functioning.
    • Testing work
      • Testing the ready software with ADC EVM DC782A-P.

2. Completed Work:

  • BeagleScope
    • Notes :
      • clpru_and_C_usage.notes [1] : Highlighting some limitations and usage information about the clpru - PRU C compiler
      • current_remoteproc_driver.notes[2]: Highlighting some of the current capabilities and insight into working of the remoteproc driver.
    • Programmable Real Time units
      • firmware
        1. The firmware that can sample 8bit wide data at frequencies lower than 25MHz. It can sample continuously in cycle and transfer data in form of data blocks using BLOCK_READ mode or can take a single sample using RAW_READ mode. [3]
        2. Various examples :
          • pru_blinky [4] : The example to make a blinky on PRUs
          • pur_logic_replicate [5] : To input logic on an input pin and reproduce it on an output pin.
          • pru1_to_pru0_to_arm [6] : example in which pru1 interrupts pru0 which further sends a message to arm.
          • PRU_inline_asm_blinky [7] : Example to make a blinky using inline assembly.
          • pur_pi_state_reader [8] : example to send logic-state of an input pin as a message to the userspace
    • Linux kernel
      • Example :
        n-blinky [9] : an example to show development of an rpmsg-client driver and associate a firmware with it.
      • The project has to be developed in 2 steps:
      • Step 1
        A single driver that registers itself as a rpmsg-client driver, it configures the PRU according to the given sampling frequency and starts sampling the data. The driver samples at 50% duty cycle and can sample at max 20MHz of sampling rate. [10]
      • Step 2 (These drivers are in wip_parallel_interface_take2 branch as of now)
        1. A platform driver specific to the platform named pi_bus.c
          The driver That register itself as a rpmsg-client driver and then as platform driver and binds with the platform-device associated with the pibus0 node (the node that represents a virtual parallel host in the device tree) [11]
        2. A generic core-bus driver named as parallel_interface.c. The core-bus device provides all the APIs required to register a device and a driver, except the devm_* based, managed APIs. It thus provides a mechanism to register a device driver and a platform-driver to provide device-to-driver bindings. [12]
        3. Some modifications in the beaglescope_driver to make it register onto the parallel_interface core-driver with some dummy probe and remove functions. [13]
    • Testing work
      The ADC EVM DC782A-P was tested with PRUs being a clock source with a clock driver circuit and the it was found to be working.


3. Things not done :

There was nothing that was completely left out. Each and every feature task/feature had some progress and was implemented with leaving some limitations. As of now:

  • The firmware can only sample 8 bit wide data, as compared to proposed configurable sampling width.
  • The firmware can sample only at maximum of 25MHz as compared to proposed max of 40MHz.
  • The drivers do not utilize the configurable duty-cycle capability of the PRU firmware.
  • Because of the above limitation, the sampling process is limited to 50% duty cycle and therefore the sampling process can reach a max of 20MHz.
  • None of the parallel_interface or pi_bus driver EXPORT any APIs to communicate to the ADC using the parallel_bus framework. It still uses RPMsg framework to get data from ADC
  • The ADC was not extensively used. PRU as the clock source for the ADC was tested. The final code is well tested on the software part and has been tested with fake data, but its not well tested with the ADC board.

4. Things done out of the proposal :

There were not a lot of things I could do out of the proposal, but I managed to develop some PRU programming examples and posts on it. Further, I was able to make some noted out of the remote-proc driver and the usage of PRU compiler 'clpru'.

  • Example :
    • firmware examples :
      • pru_blinky [4] : The example to make a blinky on PRUs
      • pur_logic_replicate [5] : To input logic on an input pin and reproduce it on an output pin.
      • pru1_to_pru0_to_arm [6] : example in which pru1 interrupts pru0 which further sends a message to arm.
      • PRU_inline_asm_blinky [7] : Example to make a blinky using inline assembly.
      • pur_pi_state_reader [8] : example to send logic-state of an input pin as a message to the userspace
    • Linux Driver example :
      n-blinky [9] : an example to show development of an rpmsg-client driver and associate a firmware with it.
  • Notes :
    • clpru_and_C_usage.notes [1] : Highlighting some limitations and usage information about the clpru - PRU C compiler
    • current_remoteproc_driver.notes[2]: Highlighting some of the current capabilities and insight into working of the remoteproc driver.
5. Obstacles :

For me, it was a learning process. Therefore, there were no hard obstacles as such, though there were some speed-breakers in the development process:
  • The most important was the less documented, and very fast changing software support to use PRU.
  • No friendly documentation of the kernel images and their associated source files.
  • PRU programming in itself is a bit challenging task, and with the newer rpmsg support, you now have to understand first the PRUs and then the rpmsg-framework.
  • Managing other tasks at home and college.

6. Things to make it better:

The things I have mentioned in the obstacles can be broadly divided in two categories :
  1. Features of community support, as it is very fast changing and usually uncertain about whats next.
  2. Managing the college curriculum and other events along with the project.
Seriously, I dont know the solution to any of these two. But what I think can make things better is, helping and encouraging students to get the right source of kernel even before the proposal and compiling it. It alone took me about 1.5 weeks and thus. Once this is clear, things would really the actual project work can be started straight and hence making students prepared for anything that was not predicted, becoming a speed breaker in the development process.

7. Further development:

As of the current status of the project, a lot future development is possible:
  1. Adding the APIs to communicate the data through the parallel_bus framework. This would involve:
    • adding APIs for PRU management in the pi_bus platform driver. The parallel_bus core driver will be the consumer of these APIs and will use them to transfer data and configure the parallel_bus host device.
    • Adding support in the parallel_interface core-bus driver to use the APIs declared by the pi_bus platform driver
    • adding APIs for parallel_data transaction in the parallel_interface core-bus driver. The device driver will be the consumer of these APIs and will use them for read and write operations.
    • developing the device driver that would be talking over the parallel_bus and exposing itself to user-space using the IIO subsystem
  2. Adding higher speed support to use configurable duty cycle option in the PRU firmware
  3. Adding MACRO to sample at a much higher but not configurable sampling rate. Aslo add configurable sampling bit width.


8. Final Words:

Hmmm (Hunyue, just borrowing this for a while :) ), so the last report. It has been a journey, at times pleasant and at times adventurous, at times learning as at times teaching, at times motivated at times depressed. No more words to describe it.

Thanks to all the member of the Beagleboard community for helping in each and every possible way. I really truly believe that you people know everything. :)

Thank you

[1] https://github.com/ZeekHuge/BeagleScope/blob/port_to_4.4.12-ti-r31%2B/docs/clpru_and_C_usage.notes
[2] https://github.com/ZeekHuge/BeagleScope/blob/port_to_4.4.12-ti-r31%2B/docs/current_remoteproc_drivers.notes
[3] https://github.com/ZeekHuge/BeagleScope/tree/port_to_4.4.12-ti-r31%2B/firmware
[4] https://github.com/ZeekHuge/BeagleScope/tree/port_to_4.4.12-ti-r31%2B/examples/firmware_exmples/pru_blinky
[5] https://github.com/ZeekHuge/BeagleScope/tree/port_to_4.4.12-ti-r31%2B/examples/firmware_exmples/pru_logic_replicate
[6] https://github.com/ZeekHuge/BeagleScope/tree/port_to_4.4.12-ti-r31%2B/examples/firmware_exmples/pru1_to_pru0_to_arm
[7] https://github.com/ZeekHuge/BeagleScope/tree/port_to_4.4.12-ti-r31%2B/examples/firmware_exmples/PRU_inline_asm_blinky
[8] https://github.com/ZeekHuge/BeagleScope/tree/port_to_4.4.12-ti-r31%2B/examples/firmware_exmples/pru_pin_state_reader
[9] https://github.com/ZeekHuge/BeagleScope/tree/port_to_4.4.12-ti-r31%2B/examples/kernel_examples/n-blinky
[10] https://github.com/ZeekHuge/BeagleScope/blob/port_to_4.4.12-ti-r31%2B/driver/beaglescope_driver.c
[11] https://github.com/ZeekHuge/BeagleScope/blob/wip_parallel_interface_take2/driver/pi_bus.c
[12] https://github.com/ZeekHuge/BeagleScope/blob/wip_parallel_interface_take2/driver/parallel_interface.c
[13] https://github.com/ZeekHuge/BeagleScope/blob/wip_parallel_interface_take2/driver/beaglescope_driver.c

leonan...@gmail.com

unread,
Nov 28, 2017, 4:29:08 AM11/28/17
to BeagleBoard GSoC
Hello,Zubeen Tolani .I want to know how to accomplish pru_rpmsg_send_large_buffer(). I can't find the code in your github .

在 2016年5月25日星期三 UTC+8下午10:59:43,Zubeen Tolani写道:

Zubeen Tolani

unread,
Nov 29, 2017, 10:22:44 AM11/29/17
to BeagleBoard GSoC
Hi !
I have answered this here in this issue - https://github.com/ZeekHuge/BeagleScope/issues/4
To make it easy, you can find the code for that method here - https://github.com/ZeekHuge/BeagleScope/blob/port_to_4.4.12-ti-r31%2B/firmware/main_pru0.c#L93
Reply all
Reply to author
Forward
0 new messages