diff --git a/index.rst b/index.rst index a7b488d467cda07c8ba58f8fed2e0b0cdb8dd486..915616d5f204f98aaf65d3f2f01c3da4c1889e24 100644 --- a/index.rst +++ b/index.rst @@ -28,6 +28,13 @@ Sections pocketbeagle/index.rst beaglebone-blue/index.rst +.. toctree:: + :maxdepth: 1 + :caption: simpPRU + + simppru/index.rst + simppru-examples/index.rst + Indices and tables ############################ diff --git a/simppru-examples/button_click_rpmsg.rst b/simppru-examples/button_click_rpmsg.rst new file mode 100644 index 0000000000000000000000000000000000000000..f21807fb41500190c615352472f41b74dafe8fc9 --- /dev/null +++ b/simppru-examples/button_click_rpmsg.rst @@ -0,0 +1,44 @@ +Sending state of button using RPMSG +=================================== + +!!! info “Schematic†=== “Pocket Beagle†|image0| + +:: + + === "BeagleBone Black / Beagle Bone Black Wireless" +  + +Code +---- + +.. code:: python + + init_message_channel(); + + while : true { + if : digital_read(P1_29) { + send_message(1); + } + else { + send_message(0); + } + delay(100); + } + +- Following code works on PocketBeagle, to use on other boards, please + change the pins accordingly. + +Explaination +------------ + +``init_message_channel`` is needed to setup communication channel +between ARM<->PRU. It only needs to be called once, before using RPMSG +functions. + +``while : true`` loop runs endlessly, inside this, we check for value of +header pin P1_29, if it reads HIGH, 1 is sent to the ARM core using +``send_message`` and if it is LOW, 0 is sent to ARM core using +``send_message``. Then PRU waits for 100ms, and repeats the steps again +and again. + +.. |image0| image:: images/led_button_pocket_beagle.png \ No newline at end of file diff --git a/simppru-examples/delay.rst b/simppru-examples/delay.rst new file mode 100644 index 0000000000000000000000000000000000000000..7d6ead6ce927384fd5d6b7f056568b50fa39bc55 --- /dev/null +++ b/simppru-examples/delay.rst @@ -0,0 +1,33 @@ +Delay example +============= + +!!! info “Schematic†=== “Pocket Beagle†|image0| + +:: + + === "BeagleBone Black / Beagle Bone Black Wireless" +  + +Code +---- + +.. code:: python + + digital_write(P1_31, true); + delay(2000); + digital_write(P1_31, false); + delay(5000); + digital_write(P1_31, true); + +- Following code works on PocketBeagle, to use on other boards, please + change the pins accordingly. + +Explaination +------------ + +This code snippet writes HIGH to header pin P1_31, then waits for 2000ms +using the ``delay`` call, after that it writes LOW to header pin P1_31, +then again waits for 5000ms using the ``delay`` call, and finally writes +HIGH to header pin P1_31. + +.. |image0| image:: images/led_pocket_beagle.png \ No newline at end of file diff --git a/simppru-examples/digital_read.rst b/simppru-examples/digital_read.rst new file mode 100644 index 0000000000000000000000000000000000000000..c39930612ddf5386ca6901753fa0234991d7b46f --- /dev/null +++ b/simppru-examples/digital_read.rst @@ -0,0 +1,36 @@ +Digital read example +==================== + +!!! info “Schematic†=== “Pocket Beagle†|image0| + +:: + + === "BeagleBone Black / Beagle Bone Black Wireless" +  + +Code +---- + +.. code:: python + + while : true { + if : digital_read(P1_29) { + digital_write(P1_31, false); + } + else { + digital_write(P1_31, true); + } + } + +- Following code works on PocketBeagle, to use on other boards, please + change the pins accordingly. + +Explaination +------------ + +This code runs a never ending loop, since it is ``while : true``. Inside +``while`` it checks if header pin P1_29 is HIGH or LOW. If header pin +P1_29 is HIGH, header pin P1_31 is set to LOW, and if header pin P1_29 +is LOW, header pin P1_31 is set to HIGH. + +.. |image0| image:: images/led_button_pocket_beagle.png \ No newline at end of file diff --git a/simppru-examples/digital_write.rst b/simppru-examples/digital_write.rst new file mode 100644 index 0000000000000000000000000000000000000000..45997aa502d5be6255a1ac21ecbb775a0a5d8f22 --- /dev/null +++ b/simppru-examples/digital_write.rst @@ -0,0 +1,29 @@ +Digital write example +===================== + +!!! info “Schematic†=== “Pocket Beagle†|image0| + +:: + + === "BeagleBone Black / Beagle Bone Black Wireless" +  + +Code +---- + +.. code:: python + + while : true { + digital_write(P1_31, true); + } + +- Following code works on PocketBeagle, to use on other boards, please + change the pins accordingly. + +Explaination +------------ + +This code runs a never ending loop, since it is ``while : true``. Inside +``while`` it sets header pin P1_31 to HIGH. + +.. |image0| image:: images/led_pocket_beagle.png diff --git a/simppru-examples/hcsr04_example_rpmsg.rst b/simppru-examples/hcsr04_example_rpmsg.rst new file mode 100644 index 0000000000000000000000000000000000000000..91fa3eccb06a4a953074c3a7b7161dcdece719ee --- /dev/null +++ b/simppru-examples/hcsr04_example_rpmsg.rst @@ -0,0 +1,71 @@ +HCSR04 Distance Sensor example (sending distance data to ARM using RPMSG) +========================================================================= + +!!! info “Schematic†=== “Pocket Beagle†|image0| + +:: + + === "BeagleBone Black / Beagle Bone Black Wireless" +  + +Code +---- + +.. code:: python + + def measure : int : { + bool timeout := false; + int echo := -1; + + start_counter(); + + while : read_counter() <= 2000 { + digital_write(5, true); + } + digital_write(5, false); + stop_counter(); + + start_counter(); + while : not (digital_read(6)) and true { + if : read_counter() > 200000000 { + timeout := true; + break; + } + } + stop_counter(); + + if : not(timeout) and true { + start_counter(); + while : digital_read(6) and true { + if : read_counter() > 200000000 { + timeout := true; + break; + } + echo := read_counter(); + } + stop_counter(); + } + + if : timeout and true { + echo := 0; + } + + return echo; + } + + init_message_channel(); + + while : true { + int ping:= measure(); + + send_message(ping); + delay(1000); + } + +- Following code works on PocketBeagle, to use on other boards, please + change the pins accordingly. + +Explaination +------------ + +.. |image0| image:: images/hcsr04_pocket_beagle.png diff --git a/simppru-examples/hcsr04_sensor.rst b/simppru-examples/hcsr04_sensor.rst new file mode 100644 index 0000000000000000000000000000000000000000..b246c1ca87392a6eb4fe464fb8329c30c0c0e552 --- /dev/null +++ b/simppru-examples/hcsr04_sensor.rst @@ -0,0 +1,75 @@ +Ultrasonic range sensor example +=============================== + +!!! info “Schematic†=== “Pocket Beagle†|image0| + +:: + + === "BeagleBone Black / Beagle Bone Black Wireless" +  + +Code +---- + +.. code:: python + + def measure : int : { + bool timeout := false; + int echo := 0; + + start_counter(); + + while : read_counter() <= 2000 { + digital_write(7, true); + } + digital_write(7, false); + stop_counter(); + + start_counter(); + while : not (digital_read(1)) and true { + if : read_counter() > 200000000 { + timeout := true; + break; + } + } + stop_counter(); + + if : not(timeout) and true { + start_counter(); + while : digital_read(1) and true { + if : read_counter() > 200000000 { + timeout := true; + break; + } + echo := read_counter(); + } + stop_counter(); + } + + if : timeout and true { + echo := 0; + } + + return echo; + } + + while : true { + int ping:= measure()*1000; + + if : ping > 292200 { + digital_write(4, false); + } + else + { + digital_write(4, true); + } + delay(1000); + } + +- Following code works on PocketBeagle, to use on other boards, please + change the pins accordingly. + +Explaination +------------ + +.. |image0| image:: images/hcsr04_pocket_beagle.png diff --git a/simppru-examples/images/hcsr04_beagle_bone_black.png b/simppru-examples/images/hcsr04_beagle_bone_black.png new file mode 100644 index 0000000000000000000000000000000000000000..8b60fc262b31ccfdc32646c3b392285e73dc72e1 Binary files /dev/null and b/simppru-examples/images/hcsr04_beagle_bone_black.png differ diff --git a/simppru-examples/images/hcsr04_pocket_beagle.png b/simppru-examples/images/hcsr04_pocket_beagle.png new file mode 100644 index 0000000000000000000000000000000000000000..efa3882b2514ebef7f83fc8ff1c10c2c90817b50 Binary files /dev/null and b/simppru-examples/images/hcsr04_pocket_beagle.png differ diff --git a/simppru-examples/images/led_beagle_bone_black.png b/simppru-examples/images/led_beagle_bone_black.png new file mode 100644 index 0000000000000000000000000000000000000000..8a7b88f375a8eb71d914b7d056b6925f71253003 Binary files /dev/null and b/simppru-examples/images/led_beagle_bone_black.png differ diff --git a/simppru-examples/images/led_button_beagle_bone_black.png b/simppru-examples/images/led_button_beagle_bone_black.png new file mode 100644 index 0000000000000000000000000000000000000000..abc3c7066f7b429040a4d98f6c4505edb2d310ce Binary files /dev/null and b/simppru-examples/images/led_button_beagle_bone_black.png differ diff --git a/simppru-examples/images/led_button_pocket_beagle.png b/simppru-examples/images/led_button_pocket_beagle.png new file mode 100644 index 0000000000000000000000000000000000000000..e2de128768ec569e243e68a4a7f5aa56d4ded47f Binary files /dev/null and b/simppru-examples/images/led_button_pocket_beagle.png differ diff --git a/simppru-examples/images/led_pocket_beagle.png b/simppru-examples/images/led_pocket_beagle.png new file mode 100644 index 0000000000000000000000000000000000000000..1b78e0e51113b1ad10a9c3a9a10adf66092d2a67 Binary files /dev/null and b/simppru-examples/images/led_pocket_beagle.png differ diff --git a/simppru-examples/index.rst b/simppru-examples/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..9530982324a7be9e4fe863bd5790b676cb890bec --- /dev/null +++ b/simppru-examples/index.rst @@ -0,0 +1,53 @@ +Welcome to simpPRU Docs +############## + +The PRU is a dual core micro-controller system present on the AM335x SoC +which powers the BeagleBone. It is meant to be used for high speed +jitter free IO control. Being independent from the linux scheduler and +having direct access to the IO pins of the BeagleBone Black, the PRU is +ideal for offloading IO intensive tasks. + +Programming the PRU is a uphill task for a beginner, since it involves +several steps, writing the firmware for the PRU, writing a loader +program. This can be a easy task for a experienced developer, but it +keeps many creative developers away. So, I propose to implement a easy +to understand language for the PRU, hiding away all the low level stuff +and providing a clean interface to program PRU. + +This can be achieved by implementing a language on top of PRU C. It will +directly compile down to PRU C. This could also be solved by +implementing a bytecode engine on the PRU, but this will result in waste +of already limited resources on PRU. With this approach, both PRU cores +can be run independent of each other. + +.. image:: images/simpPRU.png + :width: 398 + :align: center + :height: 200 + :alt: simpPRU + + +What is simpPRU +--------------- + +- simpPRU is a procedural programming language. +- It is a statically typed language. Variables and functions must be + assigned data types during compilation. +- It is typesafe, and data types of variables are decided during + compilation. +- simPRU codes have a ``.sim`` extension. +- simpPRU provides a console app to use Remoteproc functionality. + + +.. toctree:: + :maxdepth: 1 + + build.rst + install.rst + language.rst + io.rst + usage-simppru.rst + usage-simppru-console.rst + + + diff --git a/simppru-examples/led_blink.rst b/simppru-examples/led_blink.rst new file mode 100644 index 0000000000000000000000000000000000000000..39fa662530dd6aec2f07e9f7c23d13a4dbcc9450 --- /dev/null +++ b/simppru-examples/led_blink.rst @@ -0,0 +1,34 @@ +LED blink example +================= + +!!! info “Schematic†=== “Pocket Beagle†|image0| + +:: + + === "BeagleBone Black / Beagle Bone Black Wireless" +  + +Code +---- + +.. code:: python + + while : 1 == 1 { + digital_write(P1_31, true); + delay(1000); + digital_write(P1_31, false); + delay(1000); + } + +- Following code works on PocketBeagle, to use on other boards, please + change the pins accordingly. + +Explaination +------------ + +This code runs a never ending loop, since it is ``while : true``. Inside +``while`` it sets header pin P1_31 to HIGH, waits for 1000ms, then sets +header pin P1_31 to LOW, then again it waits for 1000ms. This loop runs +endlessly, so we get a Blinking output if one connects a LED + +.. |image0| image:: images/led_pocket_beagle.png diff --git a/simppru-examples/led_blink_button.rst b/simppru-examples/led_blink_button.rst new file mode 100644 index 0000000000000000000000000000000000000000..45374e3445ea57745be316f3a926b6d9c219c424 --- /dev/null +++ b/simppru-examples/led_blink_button.rst @@ -0,0 +1,38 @@ +LED blink on button press example +================================= + +!!! info “Schematic†=== “Pocket Beagle†|image0| + +:: + + === "BeagleBone Black / Beagle Bone Black Wireless" +  + +Code +---- + +.. code:: python + + while : true { + if : digital_read(P1_29) { + digital_write(P1_31, false); + } + else { + digital_write(P1_31, true); + } + } + +- Following code works on PocketBeagle, to use on other boards, please + change the pins accordingly. + +Explaination +------------ + +This code runs a never ending loop, since it is ``while : true``. Inside +``while`` if header pin P1_29 is HIGH, then header pin P1_31 is set to +HIGH, waits for 1000ms, then sets header pin P1_31 to LOW, then again it +waits for 1000ms. This loop runs endlessly as long as header pin P1_29 +is HIGH, so we get a Blinking output if one connects a LED to output +pin. + +.. |image0| image:: images/led_button_pocket_beagle.png diff --git a/simppru-examples/led_blink_counter.rst b/simppru-examples/led_blink_counter.rst new file mode 100644 index 0000000000000000000000000000000000000000..a2641cf1a99942213e21fc767d90b8350d5ea010 --- /dev/null +++ b/simppru-examples/led_blink_counter.rst @@ -0,0 +1,53 @@ +LED blink using hardware counter +================================ + +!!! info “Schematic†=== “Pocket Beagle†|image0| + +:: + + === "BeagleBone Black / Beagle Bone Black Wireless" +  + +Code +---- + +.. code:: python + + while : true { + start_counter(); + while : read_counter() < 200000000 { + digital_write(P1_31, true); + } + stop_counter(); + + start_counter(); + while : read_counter() < 200000000 { + digital_write(P1_31, false); + } + stop_counter(); + } + +- Following code works on PocketBeagle, to use on other boards, please + change the pins accordingly. + +Explaination +------------ + +This code runs a never ending while loop, since it is ``while : true``. +Inside ``while`` it starts the counter, then in a nested while loop, +which runs as long as ``read_counter`` returns values less than +200000000, so for 200000000 cycles, HIGH is written to header pin P1_31, +and after the while loop ends, the counter is stopped. + +Similarly counter is started again, which runs as long as +``read_counter`` returns a value less than 200000000, so for 200000000 +cycles, LOW is written to header pin P1_31, and after the while loop +ends, the counter is stopped. + +This process goes on endlessly as it is inside a never ending while +loop. Here, we check if ``read_counter`` is less than 200000000, as +counter takes exactly 1 second to count this much cycles, so basically +the LED is turned on for 1 second, and then turned off for 1 second. +Thus if a LED is connected to the pin, we get a endlessly blinking LED. + +.. |image0| image:: images/led_pocket_beagle.png diff --git a/simppru-examples/led_blink_for.rst b/simppru-examples/led_blink_for.rst new file mode 100644 index 0000000000000000000000000000000000000000..dda15efb2620172a2f4e26fb9075c57fe487e1ef --- /dev/null +++ b/simppru-examples/led_blink_for.rst @@ -0,0 +1,36 @@ +LED blink using for loop example +================================ + +!!! info “Schematic†=== “Pocket Beagle†|image0| + +:: + + === "BeagleBone Black / Beagle Bone Black Wireless" + ; + delay(1000); + digital_write(P1_31, false); + delay(1000); + } + +- Following code works on PocketBeagle, to use on other boards, please + change the pins accordingly. + +Explaination +------------ + +This code runs for loop with 10 iterations, Inside ``for`` it sets +header pin P1_31 to HIGH, waits for 1000ms, then sets header pin P1_31 +to LOW, then again it waits for 1000ms. This loop runs endlessly, so we +get a Blinking output if one connects a LED. So LED will blink 10 times +with this code. + +.. |image0| image:: images/led_pocket_beagle.png diff --git a/simppru-examples/led_blink_while.rst b/simppru-examples/led_blink_while.rst new file mode 100644 index 0000000000000000000000000000000000000000..6227fcb6c5fb7b8e29529aeb3d58bfef028113e8 --- /dev/null +++ b/simppru-examples/led_blink_while.rst @@ -0,0 +1,34 @@ +LED blink using while loop example +================================== + +!!! info “Schematic†=== “Pocket Beagle†|image0| + +:: + + === "BeagleBone Black / Beagle Bone Black Wireless" +  + +Code +---- + +.. code:: python + + while : true { + digital_write(P1_31, true); + delay(1000); + digital_write(P1_31, false); + delay(1000); + } + +- Following code works on PocketBeagle, to use on other boards, please + change the pins accordingly. + +Explaination +------------ + +This code runs a never ending while loop, since it is ``while : true``. +Inside ``while`` it sets header pin P1_31 to HIGH, waits for 1000ms, +then sets header pin P1_31 to LOW, then again it waits for 1000ms. This +loop runs endlessly, so we get a Blinking output if one connects a LED + +.. |image0| image:: images/led_pocket_beagle.png diff --git a/simppru-examples/read_counter.rst b/simppru-examples/read_counter.rst new file mode 100644 index 0000000000000000000000000000000000000000..a9e2c1932648a655a8cefc1b829d8cc1180f6a67 --- /dev/null +++ b/simppru-examples/read_counter.rst @@ -0,0 +1,31 @@ +Read hardware counter example +============================= + +Code +---- + +.. code:: python + + start_counter(); + while : read_counter() < 200000000 { + digital_write(4, true); + } + stop_counter(); + +- Following code works on PocketBeagle, to use on other boards, please + change the pins accordingly. + +Explaination +------------ + +Since, PRU's hardware counter works at 200 MHz, it counts upto 2 x 108 +cycles in 1 second. So, this can be reliably used to count time without +using ``delay``, as we can find exactly how much time 1 cycle takes. + +| 2 x 108 cycles/second. +| 1 Cycles = 0.5 x 10-8 seconds. + +So, it can be used to count how many cycles have passed since, say we +received a high input on pin 3. ``start_counter`` starts the counter, +and ``read_counter`` reads the current state of the counter, and +``stop_counter`` stops the counter. diff --git a/simppru-examples/rpmsg_example.rst b/simppru-examples/rpmsg_example.rst new file mode 100644 index 0000000000000000000000000000000000000000..951f0fa2eec82265145b8c6cf99e9c137c31ad6b --- /dev/null +++ b/simppru-examples/rpmsg_example.rst @@ -0,0 +1,43 @@ +Using RPMSG to communicate with ARM core +======================================== + +Code +---- + +.. code:: python + + init_message_channel(); + + int count := receive_message(); + + while : true { + send_message(count); + count := count + 1; + delay(1000); + } + +- Following code works on PocketBeagle, to use on other boards, please + change the pins accordingly. + +Explaination +------------ + +PRU has a functionality to communicate with the ARM core, it is called +RPMSG. This examples show how to use RPMSG functionality to communicate +with ARM core using RPMSG. + +``init_message_channel`` is needed to setup communication channel +between ARM<->PRU. It only needs to be called once, before using RPMSG +functions. + +``int count := receive_message();`` waits for a message from ARM Core, +we need to send some integer to PRU with which to start the counting. +So, say we send 3, then int variable count will be equal to 3. + +After this, there is ``while : true`` block which runs endlessly. Inside +the block there is a ``send_message`` call, this sends message back to +the ARM Core. + +So, inside the for loop we are sending value of count variable, after +this we increase value of count by 1. Then we wait for 1000ms, and +repeat the above steps again and again. diff --git a/simppru-examples/rpmsg_pru_calculator.rst b/simppru-examples/rpmsg_pru_calculator.rst new file mode 100644 index 0000000000000000000000000000000000000000..5449f1de3c864051b85b263f33d8a65c0f6d36ae --- /dev/null +++ b/simppru-examples/rpmsg_pru_calculator.rst @@ -0,0 +1,60 @@ +Using RPMSG to implement a simple calculator on PRU +=================================================== + +Code +---- + +.. code:: python + + init_message_channel(); + + while : true { + int option := receive_message(); + int a := receive_message(); + int b := receive_message(); + + if : option == 1 { + send_message(a+b); + } + elif : option == 2 { + send_message(a-b); + } + elif : option == 3 { + send_message(a*b); + } + elif : option == 4 { + if : b != 0 { + send_message(a/b); + } + else { + send_message(a); + } + } + else + { + send_message(a+b); + } + } + +- Following code works on PocketBeagle, to use on other boards, please + change the pins accordingly. + +Explaination +------------ + +``init_message_channel();`` starts the message channel for communication +with ARM <-> PRU cores. Then ``while : true`` loops runs endlessly. + +``int option := receive_message();`` receives which operator to be +executed and stores it in option variable. 1 for addition, 2 for +subtractions, 3 for multiplication and 4 for division. +``int a := receive_message();`` receives the value of first operand, and +``int b := receive_message();`` receives the value of second operand. + +if-elseif ladder checks if value of option is 1, 2, 3 or 4 and +accordingly sends the value of operation back to ARM core using +``send_message``. While division, it makes sure that divisor is not 0. +If value of option is anything other than 1, 2, 3, 4, then it defaults +to else condition, that is a+b. + +This runs endlessly since it is inside a ``while : true`` loop. diff --git a/simppru/build.rst b/simppru/build.rst new file mode 100644 index 0000000000000000000000000000000000000000..b63f107db13551379d42841dc286e268afcdf33a --- /dev/null +++ b/simppru/build.rst @@ -0,0 +1,38 @@ +Build from source +================= + +Dependencies +------------ + +- flex +- bison +- gcc +- gcc-pru +- gnuprumcu +- cmake + +Build +----- + +.. code:: bash + + git clone https://github.com/VedantParanjape/simpPRU.git + cd simpPRU + mkdir build + cd build + cmake .. + make + +Install +------- + +.. code:: bash + + sudo make install + +Generate debian package +----------------------- + +.. code:: bash + + sudo make package diff --git a/simppru/images/main_screen.png b/simppru/images/main_screen.png new file mode 100644 index 0000000000000000000000000000000000000000..703e8e630a40df5496047b390b9ba3cec00bddc2 Binary files /dev/null and b/simppru/images/main_screen.png differ diff --git a/simppru/images/receive_counter.png b/simppru/images/receive_counter.png new file mode 100644 index 0000000000000000000000000000000000000000..670367404813a51fece1715805ffe24596cdb3f6 Binary files /dev/null and b/simppru/images/receive_counter.png differ diff --git a/simppru/images/receive_counter_2.png b/simppru/images/receive_counter_2.png new file mode 100644 index 0000000000000000000000000000000000000000..2914493965a15e9317b4921f5a72d2483a6fa81b Binary files /dev/null and b/simppru/images/receive_counter_2.png differ diff --git a/simppru/images/receive_screen.png b/simppru/images/receive_screen.png new file mode 100644 index 0000000000000000000000000000000000000000..367dcc398175989f494856db2b550aff067b6954 Binary files /dev/null and b/simppru/images/receive_screen.png differ diff --git a/simppru/images/receive_screen_2.png b/simppru/images/receive_screen_2.png new file mode 100644 index 0000000000000000000000000000000000000000..24b6c3a66b4eea1bd1ea28d567a309f36ffc0406 Binary files /dev/null and b/simppru/images/receive_screen_2.png differ diff --git a/simppru/images/select_pru_id_screen.png b/simppru/images/select_pru_id_screen.png new file mode 100644 index 0000000000000000000000000000000000000000..e60d48ef52fa4e1e5df235998d3b77c381071bbd Binary files /dev/null and b/simppru/images/select_pru_id_screen.png differ diff --git a/simppru/images/send_screen.png b/simppru/images/send_screen.png new file mode 100644 index 0000000000000000000000000000000000000000..58e6969c9b99c76e6d957b53ab767d3733300a8c Binary files /dev/null and b/simppru/images/send_screen.png differ diff --git a/simppru/images/simpPRU.png b/simppru/images/simpPRU.png new file mode 100644 index 0000000000000000000000000000000000000000..8bd57d860b6b740b9d44ad037cc5d709722ff060 Binary files /dev/null and b/simppru/images/simpPRU.png differ diff --git a/simppru/images/stop_screen.png b/simppru/images/stop_screen.png new file mode 100644 index 0000000000000000000000000000000000000000..7f90db45071de3f7c8da29a5f7d10b62055710e9 Binary files /dev/null and b/simppru/images/stop_screen.png differ diff --git a/simppru/index.rst b/simppru/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..2e6f4d2709c7fc7570da6be370cdcc16833cad9c --- /dev/null +++ b/simppru/index.rst @@ -0,0 +1,53 @@ +Welcome to simpPRU Docs +############## + +The PRU is a dual core micro-controller system present on the AM335x SoC +which powers the BeagleBone. It is meant to be used for high speed +jitter free IO control. Being independent from the linux scheduler and +having direct access to the IO pins of the BeagleBone Black, the PRU is +ideal for offloading IO intensive tasks. + +Programming the PRU is a uphill task for a beginner, since it involves +several steps, writing the firmware for the PRU, writing a loader +program. This can be a easy task for a experienced developer, but it +keeps many creative developers away. So, I propose to implement a easy +to understand language for the PRU, hiding away all the low level stuff +and providing a clean interface to program PRU. + +This can be achieved by implementing a language on top of PRU C. It will +directly compile down to PRU C. This could also be solved by +implementing a bytecode engine on the PRU, but this will result in waste +of already limited resources on PRU. With this approach, both PRU cores +can be run independent of each other. + +.. image:: images/simpPRU.png + :width: 398 + :align: center + :height: 200 + :alt: simpPRU + + +What is simpPRU +--------------- + +- simpPRU is a procedural programming language. +- It is a statically typed language. Variables and functions must be + assigned data types during compilation. +- It is typesafe, and data types of variables are decided during + compilation. +- simPRU codes have a ``.sim`` extension. +- simpPRU provides a console app to use Remoteproc functionality. + + +.. toctree:: + :maxdepth: 1 + + build.rst + install.rst + language.rst + io.rst + usage-simppru.rst + usage-simppru-console.rst + + + diff --git a/simppru/install.rst b/simppru/install.rst new file mode 100644 index 0000000000000000000000000000000000000000..259f9a22362bc2d9432b25fec6aeb88b28f8b548 --- /dev/null +++ b/simppru/install.rst @@ -0,0 +1,66 @@ +Install +======= + +Dependencies +------------ + +- gcc-pru +- gnuprumcu +- config-pin utility (for autoconfig) + +Installation +------------ + +For Instructions head over to +`Installation <https://simppru.readthedocs.io/en/latest/install/install/>`__ + +Requirements +------------ + +Currently this only supports am335x systems: PocketBeagle, BeagleBone +Black and BeagleBone Black Wireless: + +- ``gcc-pru`` +- ``gnuprumcu`` +- beaglebone image with official support for remoteproc: + ``ti-4.19+ kernel`` +- ``config-pin`` utility + +Build from source +----------------- + +For Instructions head over to `Building from +source <https://simppru.readthedocs.io/en/latest/install/build/>`__ + + .. code:: bash + + simppru-console + + For detailed usage head to `Detailed + Usage <https://simppru.readthedocs.io/en/latest/usage/usage-simppru-console>`__ + +amd64 +----- + +.. code:: bash + + wget https://github.com/VedantParanjape/simpPRU/releases/download/1.4/simppru-1.4-amd64.deb + + sudo dpkg -i simppru-1.4-amd64.deb + +armhf +----- + +.. code:: bash + + wget https://github.com/VedantParanjape/simpPRU/releases/download/1.4/simppru-1.4-armhf.deb + + sudo dpkg -i simppru-1.4-armhf.deb + +Issues +------ + +- For full source code of simPRU + `visit <https://github.com/VedantParanjape/simppru>`__ +- To report a bug or start a issue + `visit <https://github.com/VedantParanjape/simppru/issues>`__ \ No newline at end of file diff --git a/simppru/io.rst b/simppru/io.rst new file mode 100644 index 0000000000000000000000000000000000000000..8b7e63e6bb07e6be75a6770509114966f14eeb52 --- /dev/null +++ b/simppru/io.rst @@ -0,0 +1,567 @@ +IO Functions +============ + +PRU<->Header pin mappings +------------------------- + +=== “PocketBeagle†=== “PRU0†\| R30 Register bit (Output) \| R31 +Register bit (Input) \| Header pin \| \| :————–: \| :————–: \| :——–: \| +\| - \| 16 \| P1_20 \| \| 7 \| 7 \| P1_29 \| \| 4 \| 4 \| P1_31 \| \| 1 +\| 1 \| P1_33 \| \| 0 \| 0 \| P1_36 \| \| - \| 15 \| P2_18 \| \| 15 \| - +\| P2_33 \| \| - \| 14 \| P2_22 \| \| 14 \| - \| P2_24 \| \| 6 \| 6 \| +P2_28 \| \| 3 \| 3 \| P2_30 \| \| 2 \| 2 \| P2_32 \| \| 5 \| 5 \| P2_34 +\| + +:: + + === "PRU1" + | R30 Register bit (Output) | R31 Register bit (Input) | Header pin | + | :--------------: | :--------------: | :--------: | + | 9 | 9 | P1_02 | + | 11 | 11 | P1_04 | + | 15 | 15 | P1_30 | + | 14 | 14 | P1_32 | + | 10 | 10 | P1_35 | + | - | 16 | P2_31 | + | 8 | 8 | P2_35 | + +=== “BeagleBone Black†=== “PRU0†\| R30 Register bit (Output) \| R31 +Register bit (Input) \| Header pin \| \| :————–: \| :————–: \| :——–: \| +\| - \| 15 \| P8_15 \| \| 15 \| - \| P8_11 \| \| - \| 14 \| P8_16 \| \| +14 \| - \| P8_12 \| \| 7 \| 7 \| P9_25 \| \| 5 \| 5 \| P9_27 \| \| 3 \| +3 \| P9_28 \| \| 1 \| 1 \| P9_29 \| \| 2 \| 2 \| P9_30 \| \| 0 \| 0 \| +P9_31 \| \| 6 \| 6 \| P9_41 \| \| 4 \| 4 \| P9_42 \| + +:: + + === "PRU1" + | R30 Register bit (Output) | R31 Register bit (Input) | Header pin | + | :--------------: | :--------------: | :--------: | + | 13 | 13 | P8_20 | + | 12 | 12 | P8_21 | + | 8 | 8 | **P8_27 | + | 10 | 10 | **P8_28 | + | 9 | 9 | **P8_29 | + | 6 | 6 | **P8_39 | + | 7 | 7 | **P8_40 | + | 4 | 4 | **P8_41 | + | 5 | 5 | **P8_42 | + | 2 | 2 | **P8_43 | + | 3 | 3 | **P8_44 | + | 0 | 0 | **P8_45 | + | 1 | 1 | **P8_46 | + + ** Before using these pins, you need to disable HDMI functionality. + You can read how to do this [here](https://archive.vn/D8Bzy) + +=== “BeagleBone Black Wireless†=== “PRU0†\| R30 Register bit (Output) +\| R31 Register bit (Input) \| Header pin \| \| :————–: \| :————–: \| +:——–: \| \| - \| 15 \| P8_15 \| \| 15 \| - \| P8_11 \| \| - \| 14 \| +P8_16 \| \| 14 \| - \| P8_12 \| \| 7 \| 7 \| P9_25 \| \| 5 \| 5 \| P9_27 +\| \| 3 \| 3 \| P9_28 \| \| 1 \| 1 \| P9_29 \| \| 2 \| 2 \| P9_30 \| \| +0 \| 0 \| P9_31 \| \| 6 \| 6 \| P9_41 \| \| 4 \| 4 \| P9_42 \| + +::/home/krishna/docs.beagleboard.io/simppru/usage/images + + === "PRU1" + | R30 Register bit (Output) | R31 Register bit (Input) | Header pin | + | :--------------: | :--------------: | :--------: | + | 13 | 13 | P8_20 | + | 12 | 12 | P8_21 | + | 8 | 8 | **P8_27 | + | 10 | 10 | **P8_28 | + | 9 | 9 | **P8_29 | + | 6 | 6 | **P8_39 | + | 7 | 7 | **P8_40 | + | 4 | 4 | **P8_41 | + | 5 | 5 | **P8_42 | + | 2 | 2 | **P8_43 | + | 3 | 3 | **P8_44 | + | 0 | 0 | **P8_45 | + | 1 | 1 | **P8_46 | + + ** Before using these pins, you need to disable HDMI functionality. + You can read how to do this [here](https://archive.vn/D8Bzy) + +=== “BeagleBone AI†=== “PRU0†\| R30 Register bit (Output) \| R31 +Register bit (Input) \| Header pin \| \| :————–: \| :————–: \| :——–: \| +\| 3 \| 3 \| P8_12 \| \| 4 \| 4 \| P8_11 \| \| 5 \| 5 \| P9_15 \| \| 17 +\| 17 \| P9_26 \| + +:: + + === "PRU1" + | R30 Register bit (Output) | R31 Register bit (Input) | Header pin | + | :--------------: | :--------------: | :--------: | + | 1 | 1 | P9_20 | + | 2 | 2 | P9_19 | + | 3 | 3 | P9_41 | + | 5 | 5 | P8_18 | + | 6 | 6 | P8_19 | + | 7 | 7 | P8_13 | + | 9 | 9 | P8_14 | + | 10 | 10 | P9_42 | + | 11 | 11 | P9_27 | + | 14 | 14 | P9_14 | + | 15 | 15 | P9_16 | + | 16 | 16 | P8_15 | + | 17 | 17 | P8_26 | + | 18 | 18 | P8_16 | + + === "PRU2" + | R30 Register bit (Output) | R31 Register bit (Input) | Header pin | + | :--------------: | :--------------: | :--------: | + | 10 | 10 | P8_33 | + | 11 | 11 | P8_31 | + | 6 | 6 | P8_38 | + | 7 | 7 | P8_36 | + | 20 | 20 | P8_08 | + | 15 | 15 | P9_13 | + | 3 | 3 | P8_39 | + | 2 | 2 | P8_42 | + | 9 | 9 | P8_35 | + | 8 | 8 | P8_34 | + | 5 | 5 | P8_37 | + | 4 | 4 | P8_40 | + | 17 | 17 | P8_28 | + | 18 | 18 | P8_29 | + | 19 | 19 | P8_30 | + | 1 | 1 | P8_41 | + | 0 | 0 | P8_44 | + | 14 | 14 | P9_11 | + + === "PRU3" + | R30 Register bit (Output) | R31 Register bit (Input) | Header pin | + | :--------------: | :--------------: | :--------: | + | 0 | 0 | P8_32 | + | 5 | 5 | P9_25 | + | 6 | 6 | P8_09 | + | 10 | 10 | P9_31 | + | 8 | 8 | P9_18 | + | 16 | 16 | P8_07 | + | 15 | 15 | P8_10 | + | 17 | 17 | P8_27 | + | 20 | 20 | P8_43 | + | 18 | 18 | P8_45 | + | 19 | 19 | P8_46 | + | 9 | 9 | P9_17 | + | 13 | 13 | P9_28 | + | 11 | 11 | P9_29 | + | 12 | 12 | P9_30 | + + ** Before using these pins, you need to disable HDMI functionality. + You can read how to do this [here](https://archive.vn/D8Bzy) + + +- All Header pins are ``constant integer variable`` by default, with + its value equal to respective R30/R31 register bit + + - Example: ``P1_20`` is an constant integer variable with value + ``16``, similary ``P1_02`` is an constant integer variable with + value ``9`` + +Digital Write +------------- + +``digital_write`` is a function which enables PRU to write given logic +level at specified output pin. It is a function with void return type +and it's parameters are ``integer`` and ``boolean``, first parameter is +the pin number to write to or PRU R30 register bit and second parameter +is ``boolean`` value to be written. ``true`` for HIGH and ``false`` for +LOW. + +Syntax +~~~~~~ + +``digital_write(pin_number, value);`` + +Parameters +^^^^^^^^^^ + +- ``pin_number`` is an integer. It must be a header pin name which + supports output, or PRU R30 Register bit. +- ``value`` is a boolean. It is used to set logic level of the output + pin, ``true`` for HIGH and ``false`` for LOW. + +Return Type +^^^^^^^^^^^ + +- ``void`` - returns nothing. + +Example +~~~~~~~ + +.. code:: python + + int a := 32; + + if : a < 32 { + digital_write(P1_29, true); + } + else { + digital_write(P1_29, false); + } + +If the value of a < 32, then pin ``P1_29`` is set to ``HIGH`` or else it +is set to ``LOW``. + +Digital Read +------------ + +``digital_read`` is a function which enables PRU to read logic level at +specified input pin. It is a function with return type ``boolean`` and +it's parameter is a ``integer`` whose value must be the pin number to be +read or PRU R31 register bit. + +.. _syntax-1: + +Syntax +~~~~~~ + +``digital_read(pin_number);`` + +.. _parameters-1: + +Parameters +^^^^^^^^^^ + +- ``pin_number`` is an integer. It must be a header pin name which + supports input, or PRU R31 Register bit. + +.. _return-type-1: + +Return Type +^^^^^^^^^^^ + +- ``boolean`` - returns the logic level of the pin number passed to it. + It returns ``true`` for HIGH and ``false`` for LOW. + +.. _example-1: + +Example +~~~~~~~ + +.. code:: python + + if digital_read(P1_20) { + digital_write(P1_29, false); + } + else { + digital_write(P1_29, true); + } + +Logic level of pin ``P1_20`` is read. If it is HIGH, then pin ``P1_29`` +is set to ``LOW``, or else it is set to ``HIGH``. + +Delay +----- + +``delay`` is a function which makes PRU wait for specified milliseconds. +When this is called PRU does absolutely nothing, it just sits there +waiting. + +.. _syntax-2: + +Syntax +~~~~~~ + +``delay(time_in_ms);`` + +.. _parameters-2: + +Parameters +^^^^^^^^^^ + +- ``time_in_ms`` is an integer. It is the amount of time PRU should + wait in milliseconds. (1000 milliseconds = 1 second). + +.. _return-type-2: + +Return Type +^^^^^^^^^^^ + +- ``void`` - returns nothing. + +.. _example-2: + +Example +~~~~~~~ + +.. code:: python + + digital_write(P1_29, true); + delay(2000); + digital_write(P1_29, false); + +Logic level of pin ``P1_29`` is set to ``HIGH``, PRU waits for *2000 ms* += *2 seconds*, and then sets the logic level of pin ``P1_29`` to +``LOW``. + +Start counter +------------- + +``start_counter`` is a function which starts PRU's internal counter. It +counts number of CPU cycles. So it can be used to count time elapsed, as +it is known that each cycle takes 5 nanoseconds. + +.. _syntax-3: + +Syntax +~~~~~~ + +``start_counter()`` + +Paramters +^^^^^^^^^ + +- n/a + +.. _return-type-3: + +Return Type +^^^^^^^^^^^ + +- ``void`` - returns nothing. + +.. _example-3: + +Example +~~~~~~~ + +.. code:: python + + start_counter(); + +Stop counter +------------ + +``stop_counter`` is a function which stops PRU's internal counter. + +.. _syntax-4: + +Syntax +~~~~~~ + +``stop_counter()`` + +.. _paramters-1: + +Paramters +^^^^^^^^^ + +- n/a + +.. _return-type-4: + +Return Type +^^^^^^^^^^^ + +- ``void`` - returns nothing. + +.. _example-4: + +Example +~~~~~~~ + +.. code:: python + + stop_counter(); + +Read counter +------------ + +``read_counter`` is a function which reads PRU's internal counter and +returns the value. It counts number of CPU cycles. So it can be used to +count time elapsed, as it is known that each cycle takes 5 nanoseconds. + +.. _syntax-5: + +Syntax +~~~~~~ + +``read_counter()`` + +.. _parameters-3: + +Parameters +^^^^^^^^^^ + +- n/a + +.. _return-type-5: + +Return Type +^^^^^^^^^^^ + +- ``integer`` - returns the number of cycles elapsed since calling + ``start_counter``. + +.. _example-5: + +Example +~~~~~~~ + +.. code:: python + + start_counter(); + + while : read_counter < 200000000 { + digital_write(P1_29, true); + } + + digital_write(P1_29, false); + stop_counter(); + +while the value of hardware counter is less than 200000000, it will set +logic level of pin ``P1_29`` to ``HIGH``, after that it will set it to +``LOW``. Here, 200000000 cpu cycles means 1 second of time, as CPU clock +is 200 MHz. So, LED will turn on for 1 second, and turn off after. + +Init message channel +-------------------- + +``init_message_channel`` is a function which is used to initialise +communication channel between PRU and the ARM core. It is sets up +necessary structures to use RPMSG to communicate, it expects a init +message from the ARM core to initialise. It is a necessary to call this +function before using any of the message functions. + +.. _syntax-6: + +Syntax +~~~~~~ + +``init_message_channel()`` + +.. _parameters-4: + +Parameters +^^^^^^^^^^ + +- n/a + +.. _return-type-6: + +Return Type +^^^^^^^^^^^ + +- ``void`` - returns nothing + +.. _example-6: + +Example +~~~~~~~ + +.. code:: python + + init_message_channel(); + +Receive message +--------------- + +``receive_message`` is a function which is used to receive messages from +ARM to the PRU, messages can only be ``integers``, as only they are +supported as of now. It uses RPMSG channel setup by +``init_message_channel`` to receive messages from ARM core. + +.. _syntax-7: + +Syntax +~~~~~~ + +``receive_message()`` + +.. _parameters-5: + +Parameters +^^^^^^^^^^ + +- n/a + +.. _return-type-7: + +Return Type +^^^^^^^^^^^ + +- ``integer`` - returns integer data received from PRU + +.. _example-7: + +Example +~~~~~~~ + +.. code:: c + + init_message_channel(); + + int emp := receive_message(); + + if : emp >= 0 { + digital_write(P1_29, true); + } + else { + digital_write(P1_29, false); + } + +Send message +------------ + +There are six functions which are used to send messages to ARM core from +PRU, messages can be ``integers``, ``characters``, ``bools``, +``integer arrays``, ``character arrays``, and ``boolean arrays``. It +uses RPMSG channel setup by ``init_message_channel`` to send messages +from PRU to the ARM core. + +For sending arrays, arrays are automatically converted to a string, for +example, [1, 2, 3, 4] would become “1 2 3 4â€. + +.. _syntax-8: + +Syntax +~~~~~~ + +- ``send_int(expression)`` + +- ``send_char(expression)`` + +- ``send_bool(expression)`` + +- ``send_ints(identifier)`` + +- ``send_chars(identifier)`` + +- ``send_bools(identifier)`` + +- ``send_message`` is an alias for ``send_int`` to preserve backwards + compatibility. + +.. _parameters-6: + +Parameters +^^^^^^^^^^ + +- For ``send_int`` and ``send_char``, ``expression`` would be an + arithmetic expression. +- For ``send_bool``, ``expression`` would be a boolean expression +- For ``send_ints``, ``identifier`` should be an identifier for an + integer array. +- For ``send_chars``, ``identifier`` should be an identifier for a + character array. +- For ``send_bools``, ``identifier`` should be an identifier for a + boolean array. + +.. _example-8: + +Example +~~~~~~~ + +.. code:: c + + init_message_channel(); + + if : digital_read(P1_29) { + send_bool(true); + } + else { + send_int(0); + } diff --git a/simppru/language.rst b/simppru/language.rst new file mode 100644 index 0000000000000000000000000000000000000000..ead310a468a5980b46968671dc9502df3b6e7ce1 --- /dev/null +++ b/simppru/language.rst @@ -0,0 +1,686 @@ +Language Syntax +=============== + +- simpPRU is a procedural programming language. +- It is a statically typed language. Variables and functions must be + assigned data types during compilation. +- It is typesafe, and data types of variables are decided during + compilation. +- simPRU codes have a ``.sim`` extension. + +Datatypes +--------- + +- ``int`` - Integer datatype +- ``bool`` - Boolean datatype +- ``char`` / ``uint8`` - Character / Unsigned 8 bit integer datatype +- ``void`` - Void datatype, can only be used a return type for + functions + +Constants +--------- + +- ``<any_integer>`` - Integer constant. Integers can be decimal, + hexadecimal (start with 0x or 0X) or octal (start with 0) +- ``'<any character>'`` - Character constant. These can be assigned to + both int and char/uint8 variables +- ``true`` - Boolean constant (True) +- ``false`` - Boolean constant (False) +- ``Px_yz`` - Pin mapping constants are Integer constant, where x is + 1,2 or 8,9 and yz are the header pin numbers. For further details + refer to `this <io.md>`__ + +Operators +--------- + +- ``{``,\ ``}`` - Braces + +- ``(``,\ ``)`` - Parenthesis + +- ``/``,\ ``*``,\ ``+``,\ ``-``,\ ``%`` - Arithmetic operators + +- ``>``,\ ``<``,\ ``==``,\ ``!=``,\ ``>=``,\ ``<=`` - Comparison + operators + +- ``~``,\ ``&``,\ ``|``,\ ``<<``,\ ``>>`` - Bitwise operators: not, + and, or and bitshifts + +- ``not``,\ ``and``,\ ``or`` - Logical operators: not, and, or + +- ``:=`` - Assignment operator + +- Result of Arithmetic and Bitwise operators is Integer constant. + +- Result of Comparison and Logical operators is Boolean constant. + +- Characters are treated as integers when used in Arithmetic + expressions. + +- Only Integer constants can be used with Arithmetic and Bitwise + operators. + +- Only Integer constants can be used with Comparison operators. + +- Only Boolean constants can be used with Logical operators. + +- Operators are evaluated following these `precedence + rules <https://en.cppreference.com/w/c/language/operator_precedence>`__. + +.. code:: cpp + + Correct: bool out := 5 > 6; + Wrong: int yy := 5 > 6; + +Variable declaration +-------------------- + +- Datatype of variable needs to be specified during compile time. +- Variables can be assigned values after declarations. +- If variable is not assigned a value after declaration, it is set to + ``0`` for ``integer`` and ``char/uint8`` and to ``false`` for + ``boolean`` by default. +- Variables can be assigned other variables of same datatype. + ``int``\ s and ``char``\ s can be assigned to each other. +- Variables can be assigned expressions whose output is of same + datatype. + +Declaration +~~~~~~~~~~~ + +.. code:: cpp + + int var; + char char_var; + bool test_var; + +Assignment during Declaration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: cpp + + int var := 99; + char char_var := 'a'; + uint8 short_var := 255; + bool test_var := false; + +Assignment +~~~~~~~~~~ + +.. code:: cpp + + var := 45; + short_var := var; + test_var := true; + +- Variables to be assigned must be declared earlier. +- Datatype of the variables cannot change. Only appropriate + expressions/constants of their respective datatypes can be assigned + to the variables. +- Integer and Character variable can be assigned only Integer + expression/Integer constant/Character constant. +- Boolean variable can be assigned only Boolean expression/constant. + +Arrays +------ + +- Arrays are static - their size has to be known at compile time and + this size cannot be changed later. +- Arrays can be used with bool, int and char. +- Arrays do not support any arithmetic / logical / comparison / bitwise + operators, however these operators work fine on their elements. + +Declaration and Assignment +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- The data type has to be specified as data_type[size]. +- Array of char can be initialized from a double quoted string, where + the length of the array would be at least the length of the string + plus 1. + +.. code:: cpp + + int[16] a; /* array of 16 integers */ + char[20] string1 := "I love BeagleBoards"; + +Indexing: +~~~~~~~~~ + +- Arrays are zero-indexed. + +- The index can be either a char or an int or an expression involving + chars and ints. + +- Accessing elements of an array: + +.. code:: cpp + + int a := arr[4]; /* Copy the 5th element of arr to a */ + +- Changing elements of an array: + +.. code:: cpp + + arr[4] := 5; /* The 5th element of arr is now 5 */ + + int i := 4; + arr[i] := 6; /* The 5th element of arr is now 6 */ + + char j := 4; + arr[j] := 7; /* The 5th element of arr is now 7 */ + + arr[i+j] := 1; /* The 9th element of arr is now 1 */ + + /* Declaring and initializing an array with all zeros */ + int[16] arr; + for: i in 0:16 { + arr[i] := 0; + } + +Comments +-------- + +- simpPRU supports C style multiline comments. + +.. code:: cpp + + /* This is a comment */ + + /* Comments can span + multiple lines */ + +Keyword and Identifiers +----------------------- + +Reserved keywords +~~~~~~~~~~~~~~~~~ + ++-------------------------+------------------------------+-----------------------+ +| **``true``** | **``read_counter``** | **``stop_counter``** | ++-------------------------+------------------------------+-----------------------+ +| **``false``** | **``start_counter``** | **``pwm``** | ++-------------------------+------------------------------+-----------------------+ +| **``int``** | **``delay``** | **``digital_write``** | ++-------------------------+------------------------------+-----------------------+ +| **``bool``** | **``digital_read``** | **``def``** | ++-------------------------+------------------------------+-----------------------+ +| **``void``** | **``return``** | **``or``** | ++-------------------------+------------------------------+-----------------------+ +| **``if``** | **``and``** | **``not``** | ++-------------------------+------------------------------+-----------------------+ +| **``elif``** | **``continue``** | **``break``** | ++-------------------------+------------------------------+-----------------------+ +| **``else``** | **``while``** | **``in``** | ++-------------------------+------------------------------+-----------------------+ +| **``for``** | **``init_message_channel``** | **``send_message``** | ++-------------------------+------------------------------+-----------------------+ +| **``receive_message``** | **``print``** | **``println``** | ++-------------------------+------------------------------+-----------------------+ + +Valid identifier naming +~~~~~~~~~~~~~~~~~~~~~~~ + +- An identifier/variable name must be start with an alphabet or + underscore (_) only, no other special characters, digits are allowed + as first character of the identifier/variable name. + + ``product_name, age, _gender`` + +- Any space cannot be used between two words of an identifier/variable; + you can use underscore (_) instead of space. + + ``product_name, my_age, gross_salary`` + +- An identifier/variable may contain only characters, digits and + underscores only. No other special characters are allowed, and we + cannot use digit as first character of an identifier/variable name + (as written in the first point). + + ``length1, length2, _City_1`` + +Detailed info: +https://www.includehelp.com/c/identifier-variable-naming-conventions.aspx + +Expressions +----------- + +Arithmetic expressions +~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: cpp + + => (9 + 8) * 2 + -1; + 33 + => 11 % 3; + 2 + => 2 * 6 << 2 + 1; + 96 + => ~0xFFFFFFFF; + 0 + +Boolean expressions +~~~~~~~~~~~~~~~~~~~ + +.. code:: cpp + + => 9 > 2 or 8 != 2 and not( 2 >= 5 or 9 <= 5 ) or 9 != 7; + true + => 0xFFFFFFFF != 0XFFFFFFFF; + false + => 'a' < 'b'; + true + +!!! Note Expressions are evaluated following the `operator +precedence <#operators>`__ + +If-else statement +----------------- + +Statements in the if-block are executed only if the if-expression +evaluates to ``true``. If the value of expression is ``true``, +statement1 and any other statements in the block are executed and the +else-block, if present, is skipped. If the value of expression is +``false``, then the if-block is skipped and the else-block, if present, +is executed. If elif-block are present, they are evaluated, if they +become ``true``, the statement is executed, otherwise, it goes on to +eval next set of statements + +Syntax +~~~~~~ + +.. code:: python + + if : boolean_expression { + statement 1 + ... + ... + } + elif : boolean_expression { + statement 2 + ... + ... + ... + } + else { + statement 3 + ... + ... + } + +Examples +~~~~~~~~ + +.. code:: python + + int a := 3; + + if : a != 4 { + a := 4; + } + elif : a > 4 { + a := 10; + } + else { + a := 0; + } + +- This will evaluate as follows, since ``a = 3``, if-block (``3!=4``) + will evaluate to true, and value of a will be set to 4, and program + execution will stop. + +For-loop statement +------------------ + +For loop is a range based for loop. Range variable is a local variable +with scope only inside the for loop. + +.. _syntax-1: + +Syntax +~~~~~~ + +.. code:: python + + for : var in start:stop { + statement 1 + .... + .... + } + +- Here, for loop is a range based loop, value of integer variable + ``var`` will vary from ``start`` to ``stop - 1``. Value of ``var`` + does not equal ``stop``. Here, ``increment`` is assumed to be 1, so + ``start`` will have to less than ``stop``. + +- Optionally, ``start`` can be skipped, and it will automatically start + from 0, like this: + +.. code:: python + + for : var in :stop { + statement 1 + .... + .... + } + +- Optionally, ``increment`` can also be specified like this. Here, + ``stop`` can be less than ``start`` if ``increment`` is negative. + +.. code:: python + + for : var in start:stop:increment { + statement 1 + .... + .... + } + +!!! Note **var** is a **integer**, and **start, stop, increment** can be +**arithmetic expression, integer or character variable, or integer or +character constant**. + +.. _examples-1: + +Examples +~~~~~~~~ + +.. code:: python + + int sum := 0; + + for : i in 1:4 { + sum = sum + i; + } + +.. code:: python + + int mx := 32; + int nt; + + for : j in 2:mx-10 { + nt := nt + j; + } + +.. code:: python + + int sum := 0; + + for : i in in 10:1:-2 { /*10, 8, 6, 4, 2*/ + sum = sum + i; + } + +While-loop statement +-------------------- + +While loop statement repeatedly executes a target statement as long as a +given condition is true. + +.. _syntax-2: + +Syntax +~~~~~~ + +.. code:: python + + while : boolean_expression { + statement 1 + ... + ... + } + +.. _examples-2: + +Examples +~~~~~~~~ + +- Infinite loop + +.. code:: python + + while true { + do_something.. + ... + } + +- Normal loop, will repeat 30 times, before exiting + +.. code:: python + + int tag := 0; + + while : tag < 30 { + tag := tag + 1; + } + +Control statements +------------------ + +!!! Note ``break`` and ``continue`` can only be used inside looping +statements + +break +~~~~~ + +``break`` is used to break execution in a loop statement, either +``for loop`` or ``while loop``. It exits the loop upon calling. + +.. _syntax-3: + +Syntax +^^^^^^ + +``break;`` + +.. _examples-3: + +Examples +^^^^^^^^ + +.. code:: python + + for : i in 0:9 { + if : i == 3 { + break; + } + } + +continue +~~~~~~~~ + +``continue`` is used to continue execution in a loop statement, either +``for loop`` or ``while loop``. + +.. _syntax-4: + +Syntax +^^^^^^ + +``continue;`` + +.. _examples-4: + +Examples +^^^^^^^^ + +.. code:: python + + for : j in 9:19 { + if : i == 12 { + continue; + } + else { + break; + } + } + +Functions +--------- + +Function definition +~~~~~~~~~~~~~~~~~~~ + +A function is a group of statements that together perform a task. You +can divide up your code into separate functions. How you divide up your +code among different functions is up to you, but logically the division +usually is such that each function performs a specific task. A function +declaration tells the compiler about a function’s name, return type, and +parameters. A function definition provides the actual body of the +function. + +!!! warning Function must be defined before calling it. + +.. _syntax-5: + +Syntax +^^^^^^ + +.. code:: python + + def <function_name> : <data_type> : <data_type> <param_name>, <data_type> <param_name>, ... { + statement 1; + ... + ... + + return <data_type>; + } + +!!! Note If return data type is void, then return statement is not +needed, and if still it is added, it must be return nothing, i.e., +something like this ``return ;`` + +!!! Warning ``return`` can only be present in the body of the function +only once, that too at the end of the function, not inside any compound +statements. + +!!! fail “Wrong†\* ``return`` inside a compound statement, this syntax +is not allowed. +``python def test : int : int a { if : a < 4 { return a; } }`` + +!!! done “Correct†\* ``return`` is not inside compound statments, It +should be placed only at the end of function definition \```python def +test : int : int a { int gf := 8; if : a < 4 { gf := 4; } + +:: + + return gf; + } + ``` + +.. _examples-5: + +Examples +^^^^^^^^ + +Examples according to return types + +=== “Integer†\```python def test_func : int : int a, int b { int aa := +a + 5; + +:: + + if : aa < 3 { + aa : = 0; + } + + return aa + b; + } + ``` + +=== “Character†\```python def next_char : char : char ch, int inc { +char chinc := ch + inc; + +:: + + return chinc; + } + ``` + +=== “Boolean†\```python def compare : bool : int val { bool ret := +false; + +:: + + if : val < 0 { + ret := true; + } + + return ret; + } + ``` + +=== “Void†\```python def example_func : void : bool qu { if : qu and +true { … do something … } } + +:: + + def example_func_v : void : { + int temp := 90; + + return; + } + ``` + +Function call +~~~~~~~~~~~~~ + +Functions can be called only if, they have been defined earlier. They +return data types according to their definition. Parameters are passed +by value. Only pass by value is supported as of now. + +.. _syntax-6: + +Syntax +^^^^^^ + +.. code:: python + + function_name(var1, var2, ..); + +.. _examples-6: + +Examples +^^^^^^^^ + +We will consider functions defined in earlier +`subsection <#examples_5>`__ + +=== “Integer†+``python int a := 55; int ret_val := test_func(4, a);`` + +=== “Character†+``python char a := 'a'; char b := next_char(a, 1);`` + +=== “Boolean†``python bool val := compare(22); compare(-2);`` + +=== “Void†``python example_func(false); example_func_v();`` + +Testing or Debugging +~~~~~~~~~~~~~~~~~~~~ + +For testing or debugging code, use the –test or -t flag to enable print, +println and stub functions. Use –preprocess to stop after generating the +C code only. Then run the generated C code (at /tmp/temp.c) using +``gcc``. + +Print functions +^^^^^^^^^^^^^^^ + +print can take either a string (double quoted) or any ``int`` / ``char`` +/ ``bool`` identifier. + +println is similar to print but also prints a newline (``\n``). + +**Examples** + +.. code:: java + + print("Hello World!"); + int a := 2; + print(a); + a := a + 2; + print(a); + println(""); + +Stub functions +^^^^^^^^^^^^^^ + +PRU specific functions will be replaced by stub functions which print +“function_name called with arguments arg_name†when called. diff --git a/simppru/usage-simppru-console.rst b/simppru/usage-simppru-console.rst new file mode 100644 index 0000000000000000000000000000000000000000..22f72965d63ba9dd5b97eac079e8bb3e90029c2d --- /dev/null +++ b/simppru/usage-simppru-console.rst @@ -0,0 +1,67 @@ +Usage +===== + +simppru-console is a console app, it can be used to send/receive message +to the PRU using RPMSG, and also start/stop the PRU. It is built to +facilitate easier way to use rpmsg and remoteproc API's to control and +communicate with the PRU + +!!! Warning Make sure to stop PRU before exiting. Press ``ctrl+c`` to +exit + +|image0| + +Features +-------- + +Use arrow keys to navigate around the textbox and buttons. + +Start/stop buttons +~~~~~~~~~~~~~~~~~~ + +Use these button to start/stop the selected PRU. If PRU is already +running, on starting simppru-console, it is automatically stopped. + +|image1| + +Send message to PRU +~~~~~~~~~~~~~~~~~~~ + +Use this text box to send data to the PRU, only *Integers* are +supported. On pressing enter, the typed message is sent. + +PRU0 is running echo program, whatever is sent is echoed back. + +|image2| + +Receive message from PRU +~~~~~~~~~~~~~~~~~~~~~~~~ + +The large box in the screen shows data received from the PRU, It runs +using a for loop, which checks if new message is arrived every 10 ms. + +- PRU is running echo program, whatever is sent is echoed back. + + |image3| |image4| + +- PRU is running countup program, it sends a increasing count every 1 + second, which starts from 0 + + |image5| |image6| + +Change PRU id +~~~~~~~~~~~~~ + +Using the radio box in the upper right corner, one can change the PRU +id, i.e. if one wants to use the features for PRU0 or PRU1 + +|image7| + +.. |image0| image:: images/main_screen.png +.. |image1| image:: images/stop_screen.png +.. |image2| image:: images/send_screen.png +.. |image3| image:: images/receive_screen.png +.. |image4| image:: images/receive_screen_2.png +.. |image5| image:: images/receive_counter.png +.. |image6| image:: images/receive_counter_2.png +.. |image7| image:: images/select_pru_id_screen.png diff --git a/simppru/usage-simppru.rst b/simppru/usage-simppru.rst new file mode 100644 index 0000000000000000000000000000000000000000..f9ca57cad364742390dad060631ede19a0e310c0 --- /dev/null +++ b/simppru/usage-simppru.rst @@ -0,0 +1,44 @@ +Usage +===== + +.. code:: bash + + simppru [OPTION...] FILE + + --device=<device_name> Select for which BeagleBoard to compile + (pocketbeagle, bbb, bbbwireless, bbai) + --load Load generated firmware to /lib/firmware/ + -o, --output=<file> Place the output into <file> + -p, --pru=<pru_id> Select which pru id (0/1) for which program is to + be compiled + --verbose Enable verbose mode (dump symbol table and ast + graph) + --preprocess Stop after generating the intermediate C + file (located at /tmp/temp.c) + -t --test Use stub functions for PRU specific functions and + enable the print functions, useful for testing and debugging + -?, --help Give this help list + --usage Give a short usage message + -V, --version Print program version + + Mandatory or optional arguments to long options are also mandatory or optional + for any corresponding short options. + +simppru autodetects BeagleBoard model and automatically configures pin +mux using config-pin. This functionality doesn't work on BeagleBone Blue +and AI. + +Say we have to compile a example file called ``test.sim``, command will +be as follows: + +.. code:: bash + + simppru test.sim --load + +If we only want to generate binary for pru0 + +.. code:: bash + + simppru test.sim -o test_firmware -p 0 + +this will generate a file named ``test_firmware.pru0``