üApp: picar-s: finalize CPS app uobject implementation

This task will convert the existing bang-bang CPS controller C implementation into a uobject invoked via hypercall. The following are the proposed sub-tasks:

  1. We will be working with forks and respective branches of the following repositories:

    • uberspark/uberxmhf.git on branch develop
    • uberspark/uberspark.git on branch develop
    • uberspark/uapp-SunFounder_PiCar-S.git on branch uobjcoll
    • uberspark/uobjcoll-SunFounder_Line_Follower.git on branch uobjcoll
    • uberspark/uobjcoll-raspberrypi-linux-i2c-bcm2835.git on branch uobjcoll-4.4.y

    Ensure the aforementioned forks/branches are upto date with the upstream repositories. The following gives an example of how to sync your fork of uberspark/uberxmhf.git ; the same can be applied to other repositories. Note these commands have to be applied on a local checkout of your fork.

    git remote add upstream https://github.com/uberspark/uberxmhf.git
    git fetch -a upstream  
    git checkout develop 
    git pull upstream develop 
    git push origin develop
  2. Build and install micro-hypervisor and I2C drivers i2c-bcm2708 from the above forks/branches and ensure baseline line-following functionality works

  3. Move all the logic of: uapp-SunFounder_PiCar-S/bangbang.c at uobjcoll · uberspark/uapp-SunFounder_PiCar-S · GitHub into: uberxmhf/uapp-picar-s.c at develop · uberspark/uberxmhf · GitHub

  4. Revise: uapp-SunFounder_PiCar-S/bangbang.c at uobjcoll · uberspark/uapp-SunFounder_PiCar-S · GitHub to just contain function calculate_angle_speed which just calls the hypercall UAPP_PICAR_S_FUNCTION_TEST with the parameters buffer, array, fw_speed, turn_angle and st. You will need to revise picar_s_param_t within: uberxmhf/picar-s.h at develop · uberspark/uberxmhf · GitHub

  5. Ensure that buffer and array is copied into 4k aligned page buffers within https://github.com/uberspark/uapp-SunFounder_PiCar-S/blob/uobjcoll/example/bangbang_shared/bangbang.c. For example see existing definition of encrypted_buffer there. This copying should be done before invoking the hypercall as in the previous step.

  6. Revise: uberxmhf/uapp-picar-s.c at develop · uberspark/uberxmhf · GitHub logic from lines 82–107 (the }else if (picar_s_function == UAPP_PICAR_S_FUNCTION_TEST){ portion) to invoke calculate_angle_speed with the supplied parameters. We will compute HMAC on the input buffer parameter as with the existing logic, but will also invoke calculate_speed and calculate_angle.

  7. Return values are passed using the picar_s_param_t structure fields in: uberxmhf/picar-s.h at develop · uberspark/uberxmhf · GitHub, you will need to define additional fields to hold return values which corresponding to result_array[0] through result_array[2].

  8. Within revised functoin calculate_angle_speed in: uapp-SunFounder_PiCar-S/bangbang.c at uobjcoll · uberspark/uapp-SunFounder_PiCar-S · GitHub, we will copy the result from the hypercall into result_array[0] through result_array[2].

  9. Rebuild micro-hypervisor, picar-s user controller and execute line-following. It should work as before.



Just went through the first 2 steps.
Need to go into refactoring as suggested in the following steps.

I did implement everything according to the steps, but do not seem to have a successful run with the car.
As always debugging is hard with hypervisor.
Will inspect the code and see if something else is missing.

It seems like there is a problem in the returned parameters from the Uber object.
Not sure if what I am doing is supported or it needs to be done in a different way.
I checked in the changes in my forks of these two repositories:

I updated the files in my fork.
Still trying to figure out how to pass parameters in both directions.
Is it the case that we have to send only variables by reference from the app to hypervisor?
Are there any other restrictions to what the reference should point to?
If you see the implementation I have you can see the intent and what needs to be changed to adhere to the hypervisor rules.

Hi @antonhristozov,

Sorry for the delay, am just trying to catch up on a bunch of things upon my return.

Parameters to and from the hypervisor are passed via page-aligned buffers that are locked in memory (e.g., via mlock). Within the hypervisor you can use the va2pa function to get the physical address of the buffer and then parse the appropriate values.

If your page-aligned, locked buffer contains a pointer to another buffer, that must also be page aligned and locked. And you will use va2pa on that pointer virtual address to get the physical address before accessing the buffer contents.

Hope that makes sense. I will take a look at your code later this evening and will add more inputs then…

I did the va2pa() for all parameters but it did not work for some.
Seem like they need to be adhering to the standards on the application side.

I modified the library and the Uber object and it worked finally with the car following the line.
Checked in the code with my changes in my forks.
Need to create pull requests.

Created two pull requests for the changes I have submitted with the working solution:

Amazing stuff @antonhristozov ! Sorry, I have not had much time to contribute to the review cycles yet. I will take a look at the PR today :slight_smile: