/* * hzp_alloc - lay TLS hzp struct in the TSD * * returns: true - everythings fine * false - ooops */ bool hzp_alloc(void) { #ifdef DRD_ME DRD_IGNORE_VAR(local_hzp); #endif local_hzp.flags.used = true; atomic_push(&hzp_threads.head, &local_hzp.lst); return true; }
void GCC_ATTR_FASTCALL hzp_deferfree(struct hzp_free *item, void *data, void (*func2free)(void *)) #endif { item->data = data; item->free_func = func2free; atomic_push(&hzp_freelist.head, &item->st); atomic_inc(&nr_free); #ifdef DEBUG_HZP_LANDMINE logg_develd("would free: %p, from %s@%u\n", data, func, line); #else logg_develd_old("would free: %p\n", data); #endif }
static noinline struct hzp *hzp_alloc_intern(void) { struct hzp *new_hzp = calloc(1, sizeof(*new_hzp)); int res; if(!new_hzp) return NULL; new_hzp->flags.used = true; atomic_push(&hzp_threads.head, &new_hzp->lst); if((res = pthread_setspecific(key2hzp, new_hzp))) { errno = res; new_hzp->flags.used = false; logg_errno(LOGF_CRIT, "hzp key not initilised?"); return NULL; } if(!new_hzp) logg_errno(LOGF_ALERT, "thread with no hzp, couldn't get one, were doomed!!"); return new_hzp; }
// sample_task - sample sensors void sample_task() { // local variable instantiation packet tx_packet; packet hello_packet; volatile int8_t val; volatile int8_t pwr_back; volatile uint8_t hw_rev; volatile uint8_t local_network_joined = FALSE; volatile uint8_t pwr_period_count = 0; volatile uint8_t temp_period_count = 0; volatile uint8_t light_period_count = 0; volatile uint8_t pwr_rcvd[3]; volatile uint8_t sensor_sampled = FALSE; volatile uint16_t local_pwr_val = 0; volatile uint16_t local_temp_val = 0; volatile uint16_t local_light_val = 0; volatile uint16_t adc_buf[2]; // print task pid printf("sample_task PID: %d.\r\n", nrk_get_pid()); // initialize sensor packet g_sensor_pkt.pwr_val = local_pwr_val; g_sensor_pkt.temp_val = local_temp_val; g_sensor_pkt.light_val = local_light_val; // initialize tx_packet tx_packet.source_id = MAC_ADDR; tx_packet.type = MSG_DATA; tx_packet.num_hops = 0; // initialize hello packet hello_packet.source_id = MAC_ADDR; hello_packet.type = MSG_HAND; hello_packet.num_hops = 0; hello_packet.payload[0] = (HARDWARE_REV >> 24) & 0xff; hello_packet.payload[1] = (HARDWARE_REV >> 16) & 0xff; hello_packet.payload[2] = (HARDWARE_REV >> 8) & 0xff; hello_packet.payload[3] = (HARDWARE_REV) & 0xff; // get the hardware rev of this node hw_rev = GET_REV(HARDWARE_REV); // Open the ATMEGA ADC device as read g_atmega_adc_fd = nrk_open(ADC_DEV_MANAGER,READ); if(NRK_ERROR == g_atmega_adc_fd) { nrk_kprintf(PSTR("Failed to open ADC driver\r\n")); } // loop forever - run th task while (1) { // check if the network has been joined local_network_joined = atomic_network_joined(); // if the network has been joined then start sampling sensors if(TRUE == local_network_joined) { // update period counts pwr_period_count++; temp_period_count++; light_period_count++; pwr_period_count %= g_pwr_period; temp_period_count %= g_temp_period; light_period_count %= g_light_period; sensor_sampled = FALSE; // sample power sensor if appropriate if((SAMPLE_SENSOR == pwr_period_count) && (HW_REV0 == hw_rev)) { // read power pwr_read(WATT, (uint8_t *)&pwr_rcvd); pwr_back = pwr_rcvd[2]; if (pwr_back < 0) { local_pwr_val = (~pwr_back) + 1; } else { local_pwr_val = pwr_back; } // // pull out dinner location // local_pwr_val = (pwr_rcvd[0] << 8) | pwr_rcvd[1]; // printf("val1: %x:%x:%x\r\n", pwr_rcvd[0], pwr_rcvd[1], pwr_rcvd[2]); // local_pwr_val = transform_pwr(local_pwr_val); // printf("val2: %d\r\n", local_pwr_val); g_sensor_pkt.pwr_val = local_pwr_val; sensor_sampled = TRUE; } // sample temperature sensor if appropriate if(SAMPLE_SENSOR == temp_period_count) { // sample analog temperature sensor via Atmega ADC if(HW_REV0 == hw_rev) { val = nrk_set_status(g_atmega_adc_fd, ADC_CHAN, CHAN_6); } else if(HW_REV1 == hw_rev) { val = nrk_set_status(g_atmega_adc_fd, ADC_CHAN, CHAN_4); } if(NRK_ERROR == val) { nrk_kprintf(PSTR("Failed to set ADC status\r\n")); } else { val = nrk_read(g_atmega_adc_fd, (uint8_t *)&adc_buf[0],2); if(NRK_ERROR == val) { nrk_kprintf(PSTR("Failed to read ADC\r\n")); } else { local_temp_val = (uint16_t)adc_buf[0]; local_temp_val = transform_temp(local_temp_val); g_sensor_pkt.temp_val = local_temp_val; sensor_sampled = TRUE; } } } // sample light sensor if appropriate if((SAMPLE_SENSOR == light_period_count) && (HW_REV1 == hw_rev)) { val = nrk_set_status(g_atmega_adc_fd, ADC_CHAN, CHAN_2); if(NRK_ERROR == val) { nrk_kprintf(PSTR("Failed to set ADC status\r\n")); } else { val = nrk_read(g_atmega_adc_fd, (uint8_t *)&adc_buf[0],2); if(NRK_ERROR == val) { nrk_kprintf(PSTR("Failed to read ADC\r\n")); } else { local_light_val = (uint16_t)adc_buf[0]; g_sensor_pkt.light_val = local_light_val; sensor_sampled = TRUE; } } } // if a sensor has been sampled, send a packet out if(TRUE == sensor_sampled) { // update sequence number tx_packet.seq_num = atomic_increment_seq_num(); // add data values to sensor packet tx_packet.payload[DATA_PWR_INDEX] = (uint8_t)((g_sensor_pkt.pwr_val >> 8) & 0xFF); tx_packet.payload[DATA_PWR_INDEX + 1] = (uint8_t)(g_sensor_pkt.pwr_val& 0xFF); tx_packet.payload[DATA_TEMP_INDEX] = (uint8_t)((g_sensor_pkt.temp_val >> 8) & 0xFF); tx_packet.payload[DATA_TEMP_INDEX + 1] = (uint8_t)(g_sensor_pkt.temp_val & 0xFF); tx_packet.payload[DATA_LIGHT_INDEX] = (uint8_t)((g_sensor_pkt.light_val >> 8) & 0xFF); tx_packet.payload[DATA_LIGHT_INDEX + 1] = (uint8_t)(g_sensor_pkt.light_val & 0xFF); tx_packet.payload[DATA_STATE_INDEX] = atomic_outlet_state(); // print the sensor info if(TRUE == g_verbose) { printf("P: %d, T: %d, L: %d\r\n", g_sensor_pkt.pwr_val, g_sensor_pkt.temp_val, g_sensor_pkt.light_val); } // add packet to data queue atomic_push(&g_data_tx_queue, &tx_packet, g_data_tx_queue_mux); } }
// rx_msg_task() - receive messages from the network void rx_msg_task() { // local variable instantiation int8_t rssi; uint8_t len; packet rx_packet; uint8_t *local_rx_buf; volatile uint8_t local_network_joined = FALSE; volatile uint8_t rx_source_id = 0; volatile uint8_t node_id; volatile uint8_t rx_payload = 0; volatile msg_type rx_type; // print task PID printf("rx_msg PID: %d.\r\n", nrk_get_pid()); // initialize network receive buffer bmac_rx_pkt_set_buffer(g_net_rx_buf, RF_MAX_PAYLOAD_SIZE); // Wait until bmac has started. while (!bmac_started ()) { nrk_wait_until_next_period (); } // loop forever - run the task while(1) { // only execute if there is a packet available if(bmac_rx_pkt_ready()) { nrk_led_set(BLUE_LED); // get the packet, parse and release local_rx_buf = bmac_rx_pkt_get(&len, &rssi); parse_msg(&rx_packet, local_rx_buf, len); bmac_rx_pkt_release(); // print incoming packet if appropriate if(TRUE == g_verbose) { nrk_kprintf(PSTR("RX: ")); print_packet(&rx_packet); } // get message parameters rx_source_id = rx_packet.source_id; rx_type = rx_packet.type; // only receive the message if it's not from this node if((GATEWAY_MAC == rx_source_id) || (SERVER_MAC == rx_source_id)) { // determine if the network has been joined local_network_joined = atomic_network_joined(); // execute the normal sequence of events if the network has been joined if(TRUE == local_network_joined) { // put the message in the right queue based on the type switch(rx_type) { // command received -> actuate or ignore case MSG_CMD: // if command is for this node and add it to the action queue. node_id = rx_packet.payload[CMD_NODE_ID_INDEX]; if(MAC_ADDR == node_id) { atomic_push(&g_act_queue, &rx_packet, g_act_queue_mux); if (TRUE == g_verbose) { nrk_kprintf(PSTR("Received command ^^^\r\n")); } } case MSG_HANDACK: case MSG_HEARTBEAT: case MSG_RESET: atomic_kick_watchdog(); break; case MSG_HAND: case MSG_DATA: case MSG_CMDACK: case MSG_NO_MESSAGE: case MSG_GATEWAY: default: break; } } // if the local_network_joined flag hasn't been set yet, check status else { // if a handshake ack has been received, then set the network joined flag. Otherwise, ignore. rx_payload = rx_packet.payload[HANDACK_NODE_ID_INDEX]; if((MSG_HANDACK == rx_type) && (MAC_ADDR == rx_payload)) { atomic_update_network_joined(TRUE); atomic_kick_watchdog(); local_network_joined = atomic_network_joined(); } } } nrk_led_clr(BLUE_LED); } nrk_wait_until_next_period(); } nrk_kprintf(PSTR("Fallthrough: rx_msg_task\r\n")); }
int main() { packet act_packet; // setup ports/uart nrk_setup_ports(); nrk_setup_uart(UART_BAUDRATE_115K2); SPI_Init(); pwr_init(); nrk_init (); nrk_time_set (0, 0); // clear all LEDs nrk_led_clr(0); nrk_led_clr(1); nrk_led_clr(2); nrk_led_clr(3); // flags g_verbose = FALSE; g_network_joined = FALSE; g_global_outlet_state = OFF; g_button_pressed = FALSE; // mutexs g_net_tx_buf_mux = nrk_sem_create(1, 8); g_act_queue_mux = nrk_sem_create(1, 8); g_cmd_tx_queue_mux = nrk_sem_create(1, 8); g_data_tx_queue_mux = nrk_sem_create(1, 8); g_seq_num_mux = nrk_sem_create(1, 8); g_network_joined_mux = nrk_sem_create(1, 8); g_global_outlet_state_mux = nrk_sem_create(1, 8); g_button_pressed_mux = nrk_sem_create(1, 8); g_net_watchdog_mux = nrk_sem_create(1, 8); // sensor periods (in seconds / 2) g_pwr_period = 2; g_temp_period = 3; g_light_period = 4; // packet queues packet_queue_init(&g_act_queue); packet_queue_init(&g_cmd_tx_queue); packet_queue_init(&g_data_tx_queue); // ensure node is initially set to "OFF" act_packet.source_id = MAC_ADDR; act_packet.type = MSG_CMD; act_packet.seq_num = 0; act_packet.num_hops = 0; act_packet.payload[CMD_CMDID_INDEX] = (uint16_t)0; act_packet.payload[CMD_NODE_ID_INDEX] = MAC_ADDR; act_packet.payload[CMD_ACT_INDEX] = OFF; atomic_push(&g_act_queue, &act_packet, g_act_queue_mux); // initialize bmac bmac_task_config (); bmac_init(13); nrk_register_drivers(); nrk_set_gpio(); nrk_create_taskset(); nrk_start (); return 0; }