-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Bluetooth: controller: Introduce ULL LLL architecture #12404
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bluetooth: controller: Introduce ULL LLL architecture #12404
Conversation
|
All checks are passing now. Review history of this comment for details about previous failed status. |
Codecov Report
@@ Coverage Diff @@
## master #12404 +/- ##
=======================================
Coverage 53.94% 53.94%
=======================================
Files 242 242
Lines 27654 27654
Branches 6717 6717
=======================================
Hits 14917 14917
Misses 9932 9932
Partials 2805 2805Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are those printk staatements intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tmp was a template role, this I will remove as part of the rework, this should not be part of the merge into master.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you are using this only to store ring buffers of pointers, then you could simplify by:
void* m[(cnt) + 1]; and get rid of s and sz altogether.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would also get rid of all the multiplications in the getters/setters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will take relook at this implementation once I resolve all the checkpatch issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you need to support non-pointer mfifos then this should be a memcpy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file needs comments on each function explaining what they do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've documented this in #12167
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that #12167 was spun out of https://github.com/NordicPlayground/zephyr-bt/pull/26 as that was the intersection between non-split and split stack.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @mped-oticon, that is a great effort. A while back I added the memq_link_t in order to make the code more readable, and with your comments this closes the circle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've documented this in #12167
That PR doesn't include mfifo but you have another branch for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remind me why we need a different fifo/list implementation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For 3 reasons:
- Memory efficiency and code size
- Latency: this is lockless unlike the kernel's FIFOs, never disables interrupts
- Independence from the kernel. This is only used on interrupt context, should never block or use kernel primitives
In essence this is a custom-made, highly efficient, lockless implementation for the specific purpose of exchanging data among different interrupt contexts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will only work with void* MFIFOs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. I've written about this in the documentation. See prev comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will only work with void* MFIFOs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh nice! Will you submit this after we merge this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem I see with these is that the registers are typically loaded first, and then the comparison is executed:
if (conn->llcp_req != conn->llcp_ack) {
13916: f890 30d0 ldrb.w r3, [r0, #208] ; 0xd0
1391a: f890 20d1 ldrb.w r2, [r0, #209] ; 0xd1
1391e: 429a cmp r2, r3
Which means that if you get interrupted between 1391a and 1391e you will be comparing a stale value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will add a commit to this PR to handle context-safety of the control procedures.
444603c to
8dac0b5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On Armv7-M this would be better served by using atomic_cas() is my opinion. I am not sure about other architectures (ping @mped-oticon and @aescolar) but on Armv7-M atomic_cas() uses CONFIG_ATOMIC_OPERATIONS_BUILTIN which then uses the builtin __atomic_compare_exchange_n. This translates into the assembly below, which in my opinion is going to be smaller in size than your code once assembled.
Note that on Armv6-M atomic_cas() disables interrupts and so there you will need the software implementation you have here.
return __atomic_compare_exchange_n(target, &old_value, new_value,
4d4: 4b17 ldr r3, [pc, #92] ; (534 <bt_ready+0x74>)
4d6: 9403 str r4, [sp, #12]
4d8: 2104 movs r1, #4
4da: f3bf 8f5b dmb ish
4de: e853 2f00 ldrex r2, [r3]
4e2: 42a2 cmp r2, r4
4e4: d103 bne.n 4ee <bt_ready+0x2e>
4e6: e843 1000 strex r0, r1, [r3]
4ea: 2800 cmp r0, #0
4ec: d1f7 bne.n 4de <bt_ready+0x1e>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: Oticon's mcu does not have atomic_cas.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the value is incremented, should we use atomic_inc(&conn->llcp_req) ?
8dac0b5 to
8fc1cbf
Compare
mped-oticon
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove DNM?
thoh-ot
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
QACK
|
@mped-oticon focusing on the CI failures, once its resolved I will remove the DNM |
207156d to
5a24a68
Compare
5a24a68 to
0bdd7c2
Compare
0bdd7c2 to
59e5cfd
Compare
subsys/bluetooth/shell/hci.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All header guards in Zephyr were recently changed to be constructed out of the full path. This file's should then be ZEPHYR_SUBSYS_BLUETOOTH_SHELL_HCI_H_
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, does this file even need a guard? Isn't it completely internal?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree will remove it.
subsys/bluetooth/shell/ll.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it appropriate for a shell module to use printk? Isn't the recommendation to use the shell's own output APIs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an oversight, will fix it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is some many duplicates of this logic bellow, can't we make a helper function to check llcp_req against llcp_ack?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree. Can we agree to create an issue and assign it to me? This is mentioned by @carlescufi to evaluate the use of atomic_CAS instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No problem, lets have it separately with use of atomic as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree. Can we agree to create an issue and assign it to me? This is mentioned by @carlescufi to evaluate the use of atomic_CAS instead.
Note: Oticon's mcu does not have atomic_cas.
Otherwise, fully agree about helper function or macro.
59e5cfd to
f3baa14
Compare
subsys/bluetooth/shell/ll.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shell_print() should not have a line terminator, so the \n needs to be removed
subsys/bluetooth/shell/ll.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
f3baa14 to
986d606
Compare
Refactored the internal LL interfaces to have return value to match the HCI error code u8_t data type. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
Missing updates to old architecture implementation towards introduction of new ULL LLL architecture. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
Preliminary work done towards Mesh extensions on the old LL architecture implementation. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
Updates related to new ULL LLL controller architecture. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
This is a squash merge of commits introducing the new split Upper Link Layer and Lower Link Layer architecture of the Bluetooth Low Energy controller. This introduces a new, improved Link Layer based on the concept of split responsibilities; The Upper Link Layer (ULL) is in charge of control procedures, inter-event scheduling and overall role management. The code for the ULL is shared among all hardware implementations. The Lower Link Layer (LLL) is responsible for the intra-event scheduling and vendor specific radio hardware access. The communication between ULL and LLL is achieved through a set of FIFOs that contain both control and data packets. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]> Signed-off-by: Alberto Escolar Piedras <[email protected]> Signed-off-by: Wolfgang Puffitsch <[email protected]> Signed-off-by: Morten Priess <[email protected]>
Fix the control procedure context safety by adding checks in thread mode control path to detect pre-emption by interrupt. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
986d606 to
e5d23a2
Compare
This Pull Request introduces a new, improved Link Layer based on the concept of split responsibilities:
The communication between ULL and LLL is achieved through a set of FIFOs that contain both control and data packets.