examples/02_unit_testing: Bazel build support

Bug: 307825072
Change-Id: I557ce077d2396fa675520775cd82abdb0d64c994
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/examples/+/210118
Reviewed-by: Ted Pudlik <tpudlik@google.com>
Lint: Lint 🤖 <android-build-ayeaye@system.gserviceaccount.com>
Commit-Queue: Anthony DiGirolamo <tonymd@google.com>
diff --git a/examples/01_blinky/BUILD.bazel b/examples/01_blinky/BUILD.bazel
index 3afe70f..a2e8dd1 100644
--- a/examples/01_blinky/BUILD.bazel
+++ b/examples/01_blinky/BUILD.bazel
@@ -15,6 +15,8 @@
 load("@bazel_skylib//rules:native_binary.bzl", "native_binary")
 load("//targets:transition.bzl", "rp2040_binary", "stm32_binary")
 
+package(default_visibility = ["//visibility:public"])
+
 cc_binary(
     name = "blinky",
     srcs = ["main.cc"],
@@ -57,15 +59,11 @@
 stm32_binary(
     name = "blinky.elf",
     binary = ":blinky",
-    # Visible to the flasher.
-    visibility = ["//tools:__pkg__"],
 )
 
 rp2040_binary(
     name = "rp2040_blinky.elf",
     binary = ":blinky",
-    # Visible to the flasher.
-    visibility = ["//tools:__pkg__"],
 )
 
 native_binary(
diff --git a/examples/02_unit_testing/BUILD.bazel b/examples/02_unit_testing/BUILD.bazel
new file mode 100644
index 0000000..4afa384
--- /dev/null
+++ b/examples/02_unit_testing/BUILD.bazel
@@ -0,0 +1,92 @@
+# Copyright 2024 The Pigweed Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+
+load(
+    "@pigweed//pw_build:pigweed.bzl",
+    "pw_cc_test",
+)
+load("//targets:transition.bzl", "rp2040_binary", "stm32_binary")
+
+package(default_visibility = ["//visibility:public"])
+
+cc_library(
+    name = "bitops",
+    srcs = ["bitops.cc"],
+    hdrs = ["public/bitops.h"],
+    includes = ["public"],
+)
+
+pw_cc_test(
+    name = "bitops_test",
+    srcs = ["bitops_test.cc"],
+    # Remove the manual tag to run this test automatically as part of 'bazel
+    # test' on the host.
+    tags = ["manual"],
+    # Otherwise run:
+    #   bazel test //examples/02_unit_testing:bitops_test
+    deps = [":bitops"],
+)
+
+cc_binary(
+    name = "test_runner_app",
+    testonly = True,
+    srcs = ["main.cc"],
+    malloc = select({
+        "@pico-sdk//bazel/constraint:rp2": "@pigweed//pw_malloc",
+        "@platforms//cpu:armv7e-m": "@pigweed//pw_malloc",
+        "//conditions:default": "@bazel_tools//tools/cpp:malloc",
+    }),
+    deps = [
+        ":bitops_test.lib",
+        "@pigweed//pw_assert:backend_impl",
+        "@pigweed//pw_chrono:system_clock",
+        "@pigweed//pw_chrono:system_timer",
+        "@pigweed//pw_log",
+        "@pigweed//pw_log:backend_impl",
+        "@pigweed//pw_system:init",
+        "@pigweed//pw_system:io",
+        "@pigweed//pw_system:rpc_server",
+        "@pigweed//pw_system:target_hooks",
+        "@pigweed//pw_system:work_queue",
+        "@pigweed//pw_unit_test:rpc_service",
+    ] + select({
+        "@pico-sdk//bazel/constraint:rp2": [
+            "@pico-sdk//src/common/pico_stdlib:pico_stdlib",
+            "@pigweed//pw_tokenizer:linker_script",
+            "@pigweed//pw_toolchain/arm_gcc:arm_none_eabi_gcc_support",
+            "@pigweed//targets/rp2040:pre_init",
+        ],
+        "@platforms//cpu:armv7e-m": [
+            "//targets/stm32f429i_disc1_stm32cube:linker_script",
+            "@pigweed//pw_tokenizer:linker_script",
+            "@pigweed//pw_toolchain/arm_gcc:arm_none_eabi_gcc_support",
+            "@pigweed//targets/stm32f429i_disc1_stm32cube:pre_init",
+        ],
+        "//conditions:default": [
+            "@pigweed//targets/host_device_simulator:boot",
+        ],
+    }),
+)
+
+stm32_binary(
+    name = "test_runner_app.elf",
+    testonly = True,
+    binary = ":test_runner_app",
+)
+
+rp2040_binary(
+    name = "rp2040_test_runner_app.elf",
+    testonly = True,
+    binary = ":test_runner_app",
+)
diff --git a/examples/02_unit_testing/bitops.cc b/examples/02_unit_testing/bitops.cc
index b7243ff..800041a 100644
--- a/examples/02_unit_testing/bitops.cc
+++ b/examples/02_unit_testing/bitops.cc
@@ -20,6 +20,7 @@
 
 int CountOnes(int val) {
   int count = 0;
+  // One possible fix to this is multiply sizeof(val) by 8.
   for (size_t i = 0; i < sizeof(val); ++i) {
     int mask = 0x1 << i;
     if ((val & mask) != 0) {
diff --git a/examples/03_rpc/BUILD.bazel b/examples/03_rpc/BUILD.bazel
index 32e01d8..2cb9f5c 100644
--- a/examples/03_rpc/BUILD.bazel
+++ b/examples/03_rpc/BUILD.bazel
@@ -99,15 +99,11 @@
 stm32_binary(
     name = "rpc_main.elf",
     binary = ":rpc_main",
-    # Visible to the flasher.
-    visibility = ["//tools:__pkg__"],
 )
 
 rp2040_binary(
     name = "rp2040_rpc_main.elf",
     binary = ":rpc_main",
-    # Visible to the flasher.
-    visibility = ["//tools:__pkg__"],
 )
 
 native_binary(
diff --git a/third_party/pigweed b/third_party/pigweed
index dcbe398..3a93dbe 160000
--- a/third_party/pigweed
+++ b/third_party/pigweed
@@ -1 +1 @@
-Subproject commit dcbe39839b38dd25381e14e61ef93cde1fdb0f82
+Subproject commit 3a93dbec943d0aa9bb20601dbcf618c956b6dbb4